Back to Skills
Auto Animate
AutoAnimate (@formkit/auto-animate) zero-config animations for React. Use for list transitions, accordions, toasts, or encountering SSR errors, animation libraries complexity.
react
By secondsky
Skill Content
# AutoAnimate
**Status**: Production Ready ✅
**Last Updated**: 2025-11-07
**Dependencies**: None (works with any React setup)
**Latest Versions**: @formkit/auto-animate@0.9.0
---
## Quick Start (2 Minutes)
### 1. Install AutoAnimate
```bash
bun add @formkit/auto-animate
```
**Why this matters:**
- Only 3.28 KB gzipped (vs 22 KB for Motion)
- Zero dependencies
- Framework-agnostic (React, Vue, Svelte, vanilla JS)
### 2. Add to Your Component
```tsx
import { useAutoAnimate } from "@formkit/auto-animate/react";
export function MyList() {
const [parent] = useAutoAnimate(); // 1. Get ref
return (
<ul ref={parent}> {/* 2. Attach to parent */}
{items.map(item => (
<li key={item.id}>{item.text}</li> {/* 3. That's it! */}
))}
</ul>
);
}
```
**CRITICAL:**
- ✅ Always use unique, stable keys for list items
- ✅ Parent element must always be rendered (not conditional)
- ✅ AutoAnimate respects `prefers-reduced-motion` automatically
- ✅ Works on add, remove, AND reorder operations
### 3. Use in Production (SSR-Safe)
For Cloudflare Workers or Next.js:
```tsx
// Use client-only import to prevent SSR errors
import { useState, useEffect } from "react";
export function useAutoAnimateSafe<T extends HTMLElement>() {
const [parent, setParent] = useState<T | null>(null);
useEffect(() => {
if (typeof window !== "undefined" && parent) {
import("@formkit/auto-animate").then(({ default: autoAnimate }) => {
autoAnimate(parent);
});
}
}, [parent]);
return [parent, setParent] as const;
}
```
---
## Known Issues Prevention
This skill prevents **10+** documented issues:
### Issue #1: SSR/Next.js Import Errors
**Error**: "Can't import the named export 'useEffect' from non EcmaScript module"
**Source**: https://github.com/formkit/auto-animate/issues/55
**Why It Happens**: AutoAnimate uses DOM APIs not available on server
**Prevention**: Use dynamic imports (see `templates/vite-ssr-safe.tsx`)
### Issue #2: Conditional Parent Rendering
**Error**: Animations don't work when parent is conditional
**Source**: https://github.com/formkit/auto-animate/issues/8
**Why It Happens**: Ref can't attach to non-existent element
**Prevention**:
```tsx
// ❌ Wrong
{showList && <ul ref={parent}>...</ul>}
// ✅ Correct
<ul ref={parent}>{showList && items.map(...)}</ul>
```
### Issue #3: Missing Unique Keys
**Error**: Items don't animate correctly or flash
**Source**: Official docs
**Why It Happens**: React can't track which items changed
**Prevention**: Always use unique, stable keys (`key={item.id}`)
### Issue #4: Flexbox Width Issues
**Error**: Elements snap to width instead of animating smoothly
**Source**: Official docs
**Why It Happens**: `flex-grow: 1` waits for surrounding content
**Prevention**: Use explicit width instead of flex-grow for animated elements
### Issue #5: Table Row Display Issues
**Error**: Table structure breaks when removing rows
**Source**: https://github.com/formkit/auto-animate/issues/7
**Why It Happens**: Display: table-row conflicts with animations
**Prevention**: Apply to `<tbody>` instead of individual rows, or use div-based layouts
### Issue #6: Jest Testing Errors
**Error**: "Cannot find module '@formkit/auto-animate/react'"
**Source**: https://github.com/formkit/auto-animate/issues/29
**Why It Happens**: Jest doesn't resolve ESM exports correctly
**Prevention**: Configure `moduleNameMapper` in jest.config.js
### Issue #7: esbuild Compatibility
**Error**: "Path '.' not exported by package"
**Source**: https://github.com/formkit/auto-animate/issues/36
**Why It Happens**: ESM/CommonJS condition mismatch
**Prevention**: Configure esbuild to handle ESM modules properly
### Issue #8: CSS Position Side Effects
**Error**: Layout breaks after adding AutoAnimate
**Source**: Official docs
**Why It Happens**: Parent automatically gets `position: relative`
**Prevention**: Account for position change in CSS or set explicitly
### Issue #9: Vue/Nuxt Registration Errors
**Error**: "Failed to resolve directive: auto-animate"
**Source**: https://github.com/formkit/auto-animate/issues/43
**Why It Happens**: Plugin not registered correctly
**Prevention**: Proper plugin setup in Vue/Nuxt config (see references/)
### Issue #10: Angular ESM Issues
**Error**: Build fails with "ESM-only package"
**Source**: https://github.com/formkit/auto-animate/issues/72
**Why It Happens**: CommonJS build environment
**Prevention**: Configure ng-packagr for Angular Package Format
---
## When to Use AutoAnimate vs Motion
### Use AutoAnimate When:
- ✅ Simple list transitions (add/remove/sort)
- ✅ Accordion expand/collapse
- ✅ Toast notifications fade in/out
- ✅ Form validation messages appear/disappear
- ✅ Zero configuration preferred
- ✅ Small bundle size critical (3.28 KB)
- ✅ Applying to existing/3rd-party code
- ✅ "Good enough" animations acceptable
### Use Motion When:
- ✅ Complex choreographed animations
- ✅ Gesture controls (drag, swipe, hover)
- ✅ Scroll-based animations
- ✅ Spring physics animations
- ✅ SVG path animations
- ✅ Keyframe control needed
- ✅ Animation variants/orchestration
- ✅ Custom easing curves
**Rule of Thumb**: Use AutoAnimate for 90% of cases, Motion for hero/interactive animations.
---
## Critical Rules
### Always Do
✅ **Use unique, stable keys** - `key={item.id}` not `key={index}`
✅ **Keep parent in DOM** - Parent ref element always rendered
✅ **Client-only for SSR** - Dynamic import for server environments
✅ **Respect accessibility** - Keep `disrespectUserMotionPreference: false`
✅ **Test with motion disabled** - Verify UI works without animations
✅ **Use explicit width** - Avoid flex-grow on animated elements
✅ **Apply to tbody for tables** - Not individual rows
### Never Do
❌ **Conditional parent** - `{show && <ul ref={parent}>}`
❌ **Index as key** - `key={index}` breaks animations
❌ **Ignore SSR** - Will break in Cloudflare Workers/Next.js
❌ **Force animations** - `disrespectUserMotionPreference: true` breaks accessibility
❌ **Animate tables directly** - Use tbody or div-based layout
❌ **Skip unique keys** - Required for proper animation
❌ **Complex animations** - Use Motion instead
---
## Configuration
AutoAnimate is zero-config by default. Optional customization:
```tsx
import { useAutoAnimate } from "@formkit/auto-animate/react";
const [parent] = useAutoAnimate({
duration: 250, // milliseconds (default: 250)
easing: "ease-in-out", // CSS easing (default: "ease-in-out")
// disrespectUserMotionPreference: false, // Keep false!
});
```
**Recommendation**: Use defaults unless you have specific design requirements.
---
## Using Bundled Resources
### Templates (templates/)
Copy-paste ready examples:
- `react-basic.tsx` - Simple list with add/remove/shuffle
- `react-typescript.tsx` - Typed setup with custom config
- `filter-sort-list.tsx` - Animated filtering and sorting
- `accordion.tsx` - Expandable sections
- `toast-notifications.tsx` - Fade in/out messages
- `form-validation.tsx` - Error messages animation
- `vite-ssr-safe.tsx` - Cloudflare Workers/SSR pattern
### References (references/)
- `auto-animate-vs-motion.md` - Decision guide for which to use
- `css-conflicts.md` - Flexbox, table, and position gotchas
- `ssr-patterns.md` - Next.js, Nuxt, Workers workarounds
### Scripts (scripts/)
- `init-auto-animate.sh` - Automated setup script
---
## Cloudflare Workers Compatibility
AutoAnimate works perfectly with Cloudflare Workers Static Assets:
✅ **Client-side only** - Runs in browser, not Worker runtime
✅ **No Node.js deps** - Pure browser code
✅ **Edge-friendly** - 3.28 KB gzipped
✅ **SSR-safe** - Use dynamic imports (see templates/)
**Vite Config**:
```typescript
export default defineConfig({
plugins: [react(), cloudflare()],
ssr: {
external: ["@formkit/auto-animate"],
},
});
```
---
## Accessibility
AutoAnimate respects `prefers-reduced-motion` **automatically**:
```css
/* User's system preference */
@media (prefers-reduced-motion: reduce) {
/* AutoAnimate disables animations automatically */
}
```
**Critical**: Never set `disrespectUserMotionPreference: true` - this breaks accessibility.
---
## Official Documentation
- **Official Site**: https://auto-animate.formkit.com
- **GitHub**: https://github.com/formkit/auto-animate
- **npm**: https://www.npmjs.com/package/@formkit/auto-animate
- **React Docs**: https://auto-animate.formkit.com/react
- **Video Tutorial**: Laracasts video (see README)
---
## Package Versions (Verified 2025-11-07)
```json
{
"dependencies": {
"@formkit/auto-animate": "^0.9.0"
},
"devDependencies": {
"react": "^19.2.0",
"vite": "^6.0.0"
}
}
```
---
## Production Example
This skill is based on production testing:
- **Bundle Size**: 3.28 KB gzipped
- **Setup Time**: 2 minutes (vs 15 min with Motion)
- **Errors**: 0 (all 10 known issues prevented)
- **Validation**: ✅ Works with Vite, Tailwind v4, Cloudflare Workers, React 19
**Tested Scenarios:**
- ✅ Filter/sort lists
- ✅ Accordion components
- ✅ Toast notifications
- ✅ Form validation messages
- ✅ SSR/Cloudflare Workers
- ✅ Accessibility (prefers-reduced-motion)
---
## Troubleshooting
### Problem: Animations not working
**Solution**: Check these common issues:
1. Is parent element always in DOM? (not conditional)
2. Do items have unique, stable keys?
3. Is ref attached to immediate parent of animated children?
### Problem: SSR/Next.js errors
**Solution**: Use dynamic import:
```tsx
useEffect(() => {
if (typeof window !== "undefined") {
import("@formkit/auto-animate").then(({ default: autoAnimate }) => {
autoAnimate(parent);
});
}
}, [parent]);
```
### Problem: Items flash instead of animating
**Solution**: Add unique keys: `key={item.id}` not `key={index}`
### Problem: Flexbox width issues
**Solution**: Use explicit width instead of `flex-grow: 1`
### Problem: Table rows don't animate
**Solution**: Apply ref to `<tbody>`, not individual `<tr>` elements
---
## Complete Setup Checklist
- [ ] Installed `@formkit/auto-animate@0.9.0`
- [ ] Using React 19+ (or Vue/Svelte)
- [ ] Added ref to parent element
- [ ] Parent element always rendered (not conditional)
- [ ] List items have unique, stable keys
- [ ] Tested with `prefers-reduced-motion`
- [ ] SSR-safe if using Cloudflare Workers/Next.js
- [ ] No flexbox width issues
- [ ] Dev server runs without errors
- [ ] Production build succeeds
---
**Questions? Issues?**
1. Check `templates/` for working examples
2. Check `references/auto-animate-vs-motion.md` for library comparison
3. Check `references/ssr-patterns.md` for SSR workarounds
4. Check official docs: https://auto-animate.formkit.com
5. Check GitHub issues: https://github.com/formkit/auto-animate/issues
---
**Production Ready?** ✅ Yes - 13.6k stars, actively maintained, zero dependencies.How to use
- Copy the skill content above
- Create a .claude/skills directory in your project
- Save as .claude/skills/claude-skills-auto-animate.md
- Use /claude-skills-auto-animate in Claude Code to invoke this skill