Back to React & React Native

auto-animate

auto-animateanimationreactnextjsssrfrontenderror-preventionui-ux
⭐ 860πŸ“„ MITπŸ•’ 2026-06-11Source β†—

Install this skill

npx skills add jezweb/claude-skills

Works across Claude Code, Cursor, Codex, Copilot & Antigravity

AutoAnimate manages DOM transitions by automatically monitoring child additions, removals, and positional changes. By applying a single reference hook to a container element, the library tracks the layout state and injects hardware-accelerated CSS animations whenever the DOM tree updates. It eliminates the need for manual keyframe definitions, state-based animation libraries, or complex exit/enter transition configurations. The tool functions by detecting structural mutations within the parent container and performing calculations to glide elements into their new positions. While effective for simple UI changes, it requires careful handling of SSR environments, strict adherence to unique key management in lists, and specific layout constraints for flexbox containers. This tool bridges the gap between static content and dynamic interfaces with minimal configuration overhead, assuming developers avoid common pitfalls related to DOM ref attachment.

When to Use This Skill

  • β€’Animating filtering or sorting operations in user-facing lists
  • β€’Adding visual feedback for dynamic inventory or cart adjustments
  • β€’Smooth transitions for expanding or collapsing UI sections
  • β€’Handling layout shifts when removing or inserting navigation menu items

How to Invoke This Skill

Example prompts that trigger this skill in Claude Code, Cursor, or Antigravity:

  • β€œMake my list items animate when they are removed
  • β€œAdd transition effects to my React list
  • β€œHow to make my sorting list move smoothly
  • β€œAutoAnimate setup for my Next.js project
  • β€œFix layout jumping when adding elements to a list

Pro Tips

  • πŸ’‘Always utilize the `useAutoAnimateSafe` pattern provided for any SSR-capable framework (like Next.js) to avoid critical runtime errors, even if you don't explicitly think you're rendering on the server.
  • πŸ’‘Before diving into complex custom animations, test auto-animate's default behavior with a simple list to confirm it integrates correctly with your component's lifecycle and state management.
  • πŸ’‘For advanced debugging, combine this skill's insights with your browser's dev tools to inspect element styles and ensure auto-animate is correctly applying its CSS transforms, especially when encountering visual glitches.

What this skill does

  • β€’Automatic hardware-accelerated layout transitions
  • β€’Zero-configuration entry and exit animation management
  • β€’Dynamic detection of list item reordering
  • β€’Support for conditional DOM rendering without manual keyframes
  • β€’Compatibility across React, Vue, Svelte, and Solid frameworks

When not to use it

  • βœ•Complex, multi-stage or orchestrated sequencing animations
  • βœ•Applications requiring precise control over easing curves and timing offsets
  • βœ•Environments where the DOM is manually manipulated outside the framework lifecycle

Example workflow

  1. Install @formkit/auto-animate as a dependency
  2. Create a hook or directive wrapper to ensure SSR safety
  3. Attach the reference provided by the hook to the parent list container
  4. Ensure each list item contains a stable and unique key prop
  5. Define fixed widths for flex children to prevent layout shaking
  6. Verify the animation flow by toggling list visibility state

Prerequisites

  • –Node.js environment
  • –A supported framework like React or Vue
  • –Basic understanding of DOM references

Pitfalls & limitations

  • !Conditional rendering of the parent container prevents the animation from attaching correctly
  • !Flexbox items with dynamic sizing cause container jitter during removal
  • !Server-side rendering environments trigger import errors if accessed during initial load

FAQ

Why is my animation jumping during list removal?
This usually happens when using flex-grow on items, which forces recalculations. Switch to fixed widths for animated items to stabilize the layout.
How do I use this with Next.js?
Because the library uses browser-native APIs, you must import it dynamically or guard the invocation within a useEffect hook to avoid server-side crashes.
Does this work with table elements?
It can be finicky with specific table-row styles. It is recommended to animate the tbody element or convert the table structure into a div-based grid.
Do I need to define keyframes?
No, the entire point of the library is to automatically calculate transitions without requiring CSS files or manual @keyframes definitions.

How it compares

Unlike manual CSS transitions or libraries like Framer Motion, AutoAnimate requires zero code to define the actual movement, automating the entire process based on DOM mutations.

Source & trust

⭐ 860 starsπŸ“„ MITπŸ•’ Updated 2026-06-11
πŸ“„ Full skill instructions β€” original source: jezweb/claude-skills
# AutoAnimate - Error Prevention Guide

**Package**: @formkit/[email protected] (current)
**Frameworks**: React, Vue, Solid, Svelte, Preact
**Last Updated**: 2026-01-21

---

## SSR-Safe Pattern (Critical for Cloudflare Workers/Next.js)

// 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;
}


**Why this matters**: Prevents Issue #1 (SSR/Next.js import errors). AutoAnimate uses DOM APIs not available on server.

---

## Known Issues Prevention (15 Documented Errors)

This skill prevents **15** 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**:

**React Pattern**:
// ❌ Wrong
{showList && <ul ref={parent}>...</ul>}

// βœ… Correct
<ul ref={parent}>{showList && items.map(...)}</ul>


**Vue.js Pattern**:
<!-- ❌ Wrong - parent conditional -->
<ul v-if="showList" ref="parent">
<li v-for="item in items" :key="item.id">{{ item.text }}</li>
</ul>

<!-- βœ… Correct - children conditional -->
<ul ref="parent">
<li v-if="showList" v-for="item in items" :key="item.id">
{{ item.text }}
</li>
</ul>


**Source**: React [Issue #8](https://github.com/formkit/auto-animate/issues/8), Vue [Issue #193](https://github.com/formkit/auto-animate/issues/193)

### 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 and Shaking Issues
**Error**: Elements snap to width instead of animating smoothly, or container shakes on remove
**Source**: Official docs, [Issue #212](https://github.com/formkit/auto-animate/issues/212)
**Why It Happens**: flex-grow: 1 waits for surrounding content, causing timing issues
**Prevention**: Use explicit width instead of flex-grow for animated elements

// ❌ Wrong - causes shaking
<ul ref={parent} style={{ display: 'flex' }}>
{items.map(item => (
<li key={item.id} style={{ flex: '1 1 auto' }}>{item.text}</li>
))}
</ul>

// βœ… Correct - fixed sizes
<ul ref={parent} style={{ display: 'flex', gap: '1rem' }}>
{items.map(item => (
<li
key={item.id}
style={{ minWidth: '200px', maxWidth: '200px' }}
>
{item.text}
</li>
))}
</ul>


**Maintainer Note**: justin-schroeder confirmed fixed sizes are required for flex containers

### 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/)

**Nuxt 3 Note**: Requires v0.8.2+ (April 2024). Earlier versions have ESM import issues fixed by Daniel Roe. See [Issue #199](https://github.com/formkit/auto-animate/issues/199)

### 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

### Issue #11: React 19 StrictMode Double-Call Bug
**Error**: Child animations don't work in React 19 StrictMode
**Source**: https://github.com/formkit/auto-animate/issues/232
**Why It Happens**: StrictMode calls useEffect twice, triggering autoAnimate initialization twice
**Prevention**: Use ref to track initialization

// ❌ Wrong - breaks in StrictMode
const [parent] = useAutoAnimate();

// βœ… Correct - prevents double initialization
const [parent] = useAutoAnimate();
const initialized = useRef(false);

useEffect(() => {
if (initialized.current) return;
initialized.current = true;
}, []);


**Note**: React 19 enables StrictMode by default in development. This affects all React 19+ projects.

### Issue #12: Broken Animation Outside Viewport
**Error**: Animations broken when list is outside viewport
**Source**: https://github.com/formkit/auto-animate/issues/222
**Why It Happens**: Chrome may not run Animation API for off-screen elements
**Prevention**: Ensure parent is visible before applying autoAnimate

const isInViewport = (element) => {
const rect = element.getBoundingClientRect();
return rect.top >= 0 && rect.bottom <= window.innerHeight;
};

useEffect(() => {
if (parent.current && isInViewport(parent.current)) {
autoAnimate(parent.current);
}
}, [parent]);


### Issue #13: Deleted Elements Overlay Existing Content
**Error**: Removed items overlay other items during fade out
**Source**: https://github.com/formkit/auto-animate/issues/231
**Why It Happens**: Exit animation maintains z-index, covering active content
**Prevention**: Add explicit z-index handling

// CSS workaround
<style>{
[data-auto-animate-target] {
z-index: -1 !important;
}
}</style>


### Issue #14: Cannot Disable During Drag & Drop
**Error**: Calling enable(false) doesn't prevent animations during drag
**Source**: https://github.com/formkit/auto-animate/issues/215
**Why It Happens**: Disable doesn't work reliably mid-drag
**Prevention**: Conditionally remove ref during drag

const [isDragging, setIsDragging] = useState(false);
const [parent] = useAutoAnimate();

return (
<ul ref={isDragging ? null : parent}>
{/* items */}
</ul>
);


### Issue #15: CSS Transform Parent Position Bug
**Error**: Items animate from wrong position after parent transform
**Source**: https://github.com/formkit/auto-animate/issues/227
**Why It Happens**: Items remember original position before transform
**Prevention**: Delay autoAnimate until transform completes

useEffect(() => {
if (showList && parent.current) {
setTimeout(() => {
autoAnimate(parent.current);
}, 300); // Match CSS transition duration
}
}, [showList]);


---

## Critical Rules (Error Prevention)

### 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

**Note**: AutoAnimate respects prefers-reduced-motion automatically (never disable this).

---

## Community Tips (Community-Sourced)

> **Note**: These tips come from community discussions. Verify against your version.

### Tip: Prevent Test Freezing with Mocked Package

**Source**: [Issue #230](https://github.com/formkit/auto-animate/issues/230) | **Confidence**: MEDIUM
**Applies to**: v0.8.2+

Tests may freeze for ~10 seconds when package is mocked. Add ResizeObserver mock:

// jest.setup.js
global.ResizeObserver = jest.fn().mockImplementation(() => ({
observe: jest.fn(),
unobserve: jest.fn(),
disconnect: jest.fn(),
}));

// __mocks__/@formkit/auto-animate.js
const autoAnimate = jest.fn(() => () => {});
const useAutoAnimate = jest.fn(() => [null, jest.fn(), jest.fn()]);
module.exports = { default: autoAnimate, useAutoAnimate };


### Tip: Memory Leak Prevention

**Source**: [Issue #180](https://github.com/formkit/auto-animate/issues/180) | **Confidence**: LOW
**Applies to**: All versions

For long-lived SPAs, ensure proper cleanup:

useEffect(() => {
const cleanup = autoAnimate(parent.current);
return () => cleanup && cleanup();
}, []);

// useAutoAnimate hook handles cleanup automatically
const [parent] = useAutoAnimate(); // Preferred


---

## Package Versions

**Latest**: @formkit/[email protected] (Sept 5, 2025)

**Recent Releases**:
- v0.9.0 (Sept 5, 2025) - Current stable
- v0.8.2 (April 10, 2024) - Fixed Nuxt 3 ESM imports, ResizeObserver guard

{
"dependencies": {
"@formkit/auto-animate": "^0.9.0"
}
}


**Framework Compatibility**: React 18+, Vue 3+, Solid, Svelte, Preact

**Important**: For Nuxt 3 users, v0.8.2+ is required. Earlier versions have ESM import issues

---

## 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

---

## Templates & References

See bundled resources:
- templates/ - Copy-paste examples (SSR-safe, accordion, toast, forms)
- references/ - CSS conflicts, SSR patterns, library comparisons

How to Use This Skill Unit

Option A: Project-Specific (Recommended)

  1. Click "Download" above
  2. In your project, create the directory: .agent/skills/auto-animate/
  3. Save the file as SKILL.md
  4. The agent will automatically discover the skill based on its description.

Option B: Global Installation (All Agents)

Save the file to these locations to make it available across all projects:

  • Claude Code: ~/.claude/skills/jezweb/claude-skills/auto-animate/SKILL.md
  • Cursor: ~/.cursor/skills/jezweb/claude-skills/auto-animate/SKILL.md
  • Antigravity: ~/.gemini/antigravity/skills/jezweb/claude-skills/auto-animate/SKILL.md

πŸš€ Install with CLI:
npx skills add jezweb/claude-skills

Read the Master Guide: Mastering Agent Skills β†’

Recommended Rules

View more rules β†’

Recommended Workflows

View more workflows β†’

Recommended MCP Servers

View more MCP servers β†’

Take It Further

Maximize your productivity with these powerful resources

πŸ“‹

Define Your Standards

Set up coding standards to ensure this workflow produces consistent, high-quality results.

Browse Rules Library
πŸ“–

Master Workflows

Learn how to create custom workflows, use Turbo Mode, and build your automation library.

Complete Guide

How to use this Skill in Claude Code & Cursor

For Claude Code (CLI)

To use this skill in Claude Code, copy the rule content into your project's custom instructions or follow our Add-Skill CLI guide. This ensures Claude follows your standards during every code generation.

For Cursor & Windsurf

For Cursor or Windsurf, individual skills are best used in the "Rules for AI" section. This specific unit helps the agent avoid react & react native issues, leading to cleaner, more efficient code.

Why the skill format matters: the standardized Agent Skills format lets your AI agent load detailed instructions only when they are relevant, keeping your prompt clean while improving results.

Source & attribution

This skill is categorized under React & React Native and is published by JezWeb, maintained in jezweb/claude-skills.

← Browse All Agent Skills
Sponsored AI assistant. Recommendations may be paid.