auto-animate
AutoAnimate (@formkit/auto-animate) zero-config animations for React. Use for list transitions, accordions, toasts, or encountering SSR errors, animation libraries complexity.
What this skill does
# AutoAnimate **Status**: Production Ready ✅ **Last Updated**: 2025-11-07 **Dependencies**: None (works with any React setup) **Latest Versions**: @formkit/[email protected] --- ## 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-mot
Related in Web Dev
generating-lwc-components
IncludedLightning Web Components with PICKLES methodology and 165-point scoring. Use this skill when the user creates or edits LWC components, builds wire service patterns, or writes Jest tests for LWC. TRIGGER when: user creates/edits LWC components, touches lwc/**/*.js, .html, .css, .js-meta.xml files, or asks about wire service, SLDS, or Jest LWC tests. DO NOT TRIGGER when: Apex classes (use generating-apex), Aura components, or Visualforce.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Set up queries with useQuery, mutations with useMutation, configure QueryClient caching strategies, implement optimistic updates, and handle infinite scroll with useInfiniteQuery. Use when: setting up data fetching in React projects, migrating from v4 to v5, or fixing object syntax required errors, query callbacks removed issues, cacheTime renamed to gcTime, isPending vs isLoading confusion, keepPreviousData removed problems.
document-processor-api
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
nutrient-document-processing
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Covers useMutationState, simplified optimistic updates, throwOnError, network mode (offline/PWA), and infiniteQueryOptions. Use when setting up data fetching, fixing v4→v5 migration errors (object syntax, gcTime, isPending, keepPreviousData), or debugging SSR/hydration issues with streaming server components.
accelint-nextjs-best-practices
IncludedNext.js performance optimization and best practices. Use when writing Next.js code (App Router or Pages Router); implementing Server Components, Server Actions, or API routes; optimizing RSC serialization, data fetching, or server-side rendering; reviewing Next.js code for performance issues; fixing authentication in Server Actions; or implementing Suspense boundaries, parallel data fetching, or request deduplication.