mcpField
A
auto-animate

auto-animate

github.com/jezwebDesign & UI1.1k355 installsUpdated 3w ago
Repository

About auto-animate

A troubleshooting skill for developers using @formkit/auto-animate. It covers framework setup, SSR concerns, and fixes for common animation and layout issues.

Key features

  1. 01SSR-safe integration guidance
  2. 02Examples for React, Vue, and others
  3. 03Fixes for 15 documented issues
  4. 04Accessibility and motion guidance
  5. 05Bundled templates and references

Use cases

  1. 01Diagnosing Next.js import errors
  2. 02Fixing flickering or misplaced list animations
  3. 03Resolving Vue or Nuxt registration issues

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/jezweb/claude-skills --skill auto-animate

After installing, type/auto-animatein Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

README.md
.claude-plugin/
plugin.json
assets/
example-template.txt
references/
auto-animate-vs-motion.md
css-conflicts.md
example-reference.md
ssr-patterns.md
scripts/
example-script.sh
init-auto-animate.sh
templates/
accordion.tsx
filter-sort-list.tsx
form-validation.tsx
react-basic.tsx
react-typescript.tsx
toast-notifications.tsx
vite-ssr-safe.tsx

Details

From the project README

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, Vue Issue #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 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

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


Templates & References

See bundled resources:

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

Comments

Markdown supported