Skip to main content
skill CX Codex

framer-motion · athevon — Claude Code skill: what it does, how to install

Guides coding agents on Framer Motion and Motion patterns in React: layout transitions, gestures, and DOM-direct motion values.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add AThevon/genjutsu --skill framer-motion -a claude-code
Open on GitHub

What framer-motion does

The skill gives AI assistants strict rules for working with Framer Motion and Motion across React 18 and 19 projects. It enforces package boundary checks: the agent must inspect package.json and keep whichever library name is installed (motion via motion/react or legacy framer-motion) rather than forcing an unprompted migration.

The guidelines detail exit handling with AnimatePresence, shared layout animations via layoutId, and gesture bindings like dragConstraints or dragElastic. It flags recent deprecations, such as replacing staggerChildren with the newer stagger() helper, while reminding the model that motion values update DOM styles directly without triggering component re-renders.

If you pair Motion 13+ with styled-components or Emotion, you must explicitly inject isValidProp via MotionConfig to avoid passing internal animation props to DOM nodes.

What it helps with

  • implement exit animations using AnimatePresence with proper keys
  • build shared layout transitions across components with layoutId
  • configure drag gestures with boundary constraints and snap-back behavior
  • create scroll-linked transformations with useScroll and useTransform
  • prevent infinite re-render loops caused by state updates inside motion callbacks

Example prompts for the agent

  • Create a modal dialog with enter and exit animations using AnimatePresence in mode wait
  • Add an animated tab indicator that slides between items using layoutId
  • Set up a draggable card component with dragConstraints and spring reset on release

How to install framer-motion

1Skills CLI (Vercel)

npx skills add AThevon/genjutsu --skill framer-motion -a claude-code

2Manually: put the files in place

~/.claude/skills/framer-motion/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/framer-motion/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about framer-motion

How to install framer-motion in Claude Code?

Run npx skills add AThevon/genjutsu --skill framer-motion -a claude-code. You can also place the skill file directly into ~/.claude/skills/framer-motion/SKILL.md.

What does the framer-motion skill do?

It instructs AI assistants on correct Framer Motion and Motion 13 practices, including exit transitions, gestures, scroll hooks, and avoiding React re-renders.

How does the skill handle the motion versus framer-motion package change?

It forbids automated migrations without user consent. The assistant inspects package.json and uses imports matching the existing dependency, using motion/react for motion and direct imports for framer-motion.

Source text

SKILL.md · MIT
---
name: framer-motion
description: "Framer Motion / Motion sub-skill - AnimatePresence, layout animations, gestures, motion values."
metadata:
  internal: true
---

> **Version-sensitive.** Every API name, SDK gate and browser-support claim below was
> verified on **2026-09-08** against primary sources. What against, and when, is in
> `_jutsu/VERSIONS.md`. If that date is old, re-verify before acting on a version number.

# Framer Motion - Sub-skill

> **Two package names, one library.** Framer Motion was renamed to Motion. `motion` and
> `framer-motion` both publish the same version (13.2.0 as of 2026-09-08): `motion` declares
> `"framer-motion": "^13.2.0"` as a dependency and `motion/react` re-exports it. Neither is
> broken, and `framer-motion` is still the one most installed projects have.
>
> **Read `package.json` and follow what is there.** Do not migrate a project from one to the
> other unless the user asks - that is Iron Rule 8 in `cast` / 10 in `paint`.
>
> | In `package.json` | Import from | Install line |
> |---|---|---|
> | `motion` | `"motion/react"` | `npm install motion` |
> | `framer-motion` | `"framer-motion"` | `npm install framer-motion` |
> | both | whichever the file you are editing already imports; say the project is mid-migration | - |
>
> Every API in this skill is identical across the two names at v13. Where a symbol is newer
> than v11, it is flagged inline. Peers: `react` / `react-dom` `^18 || ^19`.

## When to use Framer Motion vs alternatives

| Criteria | Framer Motion | GSAP | Native CSS |
|---------|--------------|------|-----------|
| Layout animations | Excellent (layoutId) | Manual | Impossible |
| Exit animations | AnimatePresence | Timeline reverse | Limited (display) |
| Gestures (drag, hover) | Native, declarative | Draggable plugin | Basic |
| Scroll-driven | useScroll + useTransform | ScrollTrigger (more powerful) | scroll-timeline |
| Complex orchestration | Variants + propagation | Timeline (more flexible) | @keyframes |
| Bundle size | ~50kb tree-shaken | ~30kb core | 0kb |
| React integration | Native, component-first | Refs + useGSAP | className toggle |

**Rule**: Framer Motion for React UI interactions (modals, toasts, reorder, shared layout). GSAP for complex timelines, cinematic scroll-driven, SVG morphing.

## AnimatePresence - Exit animations

```tsx
<AnimatePresence mode="wait">
  {isVisible && (
    <motion.div
      key="unique-key"        // REQUIRED - identifies the component
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      exit={{ opacity: 0 }}
    />
  )}
</AnimatePresence>
```

- `mode="wait"` - waits for exit to finish before enter (page transitions)
- `mode="sync"` - exit and enter simultaneously
- `mode="popLayout"` - removes from flow immediately (good for lists)
- `onExitComplete` - callback when all exit animations are finished

## Layout animations

```tsx
// Shared layout - the element "slides" between two positions
<motion.div layoutId="highlight" className={activeTab === id ? "active" : ""} />

// Auto layout - animates position/size when layout changes
<motion.div layout>
  {isExpanded && <motion.p layout>Additional content</motion.p>}
</motion.div>

// layout="position" - animates position only (not size)
// layout="size" - animates size only
// layout="preserve-aspect" - preserves the ratio during the transition
```

## Variants - Propagation and orchestration

```tsx
import { stagger } from "motion/react";

const container = {
  hidden: { opacity: 0 },
  show: {
    opacity: 1,
    transition: {
      // staggerChildren + staggerDirection are DEPRECATED (Motion 12.22, Jul 2025).
      // Pass a stagger() function to delayChildren instead.
      delayChildren: stagger(0.08, { startDelay: 0.2 }),
      // reverse order: stagger(0.08, { from: "last" })
      // also available: from: "first" | "center" | "last" | index, and ease
    },
  },
};

const item = {
  hidden: { opacity: 0, y: 20 },
  show: { opacity: 1, y: 0 },
};

<motion.ul variants={container} initial="hidden" animate="show">
  {items.map((i) => (
    <motion.li key={i.id} variants={item} />
  ))}
</motion.ul>
```

Variants **automatically propagate** to motion children - no need for `initial`/`animate` on children.

## Gestures

```tsx
<motion.div
  whileHover={{ scale: 1.05 }}
  whileTap={{ scale: 0.95 }}
  whileFocus={{ borderColor: "#3b82f6" }}
  // Drag
  drag               // true = x+y, "x" = horizontal only, "y" = vertical only
  dragConstraints={{ left: -100, right: 100, top: -50, bottom: 50 }}
  dragElastic={0.2}  // 0 = rigid, 1 = free (default 0.35)
  dragSnapToOrigin   // returns to initial position
  onDragEnd={(e, info) => {
    if (info.offset.x > 100) handleSwipe("right");
  }}
/>
```

## Motion values - Reactive without re-render

```tsx
const x = useMotionValue(0);
const opacity = useTransform(x, [-200, 0, 200], [0, 1, 0]);
const background = useTransform(x, [-200, 200], ["#ff0000", "#00ff00"]);

// Spring-based smoothing
const smoothX = useSpring(x, { stiffness: 300, damping: 30 });

// Scroll tracking
const { scrollY, scrollYProgress } = useScroll();
const parallaxY = useTransform(scrollYProgress, [0, 1], [0, -300]);

// Element-scoped scroll
const ref = useRef(null);
const { scrollYProgress } = useScroll({
  target: ref,
  offset: ["start end", "end start"],
});
```

**Motion values do NOT trigger React re-renders** - they update the DOM directly via `style`.

## Do Not

### Do not use motion with styled-components / Emotion without `isValidProp` (v13+)

Motion 13.0 removed `@emotion/is-prop-valid` as an optional dependency. Without explicit injection, motion-only props leak onto the DOM.

```tsx
import isPropValid from "@emotion/is-prop-valid";
import { MotionConfig } from "motion/react";

<MotionConfig isValidProp={isPropValid}>
  <App />
</MotionConfig>
```

Or reverse the composition so the styling library owns prop forwarding: `const MotionDiv = motion.create(StyledDiv)`.

### Do not setState in callbacks without a guard

```tsx
// BAD - infinite re-render if animate depends on state
onUpdate={(latest) => setPosition(latest.x)}

// GOOD - guard or useMotionValueEvent
const x = useMotionValue(0);
useMotionValueEvent(x, "change", (latest) => {
  if (latest > threshold) onThresholdReached();
});
```

### Do not use layout animation without a stable key

```tsx
// BAD - key changes every render, breaks layout tracking
<motion.div layout key={Math.random()} />

// GOOD - stable key derived from data
<motion.div layout key={item.id} />
```

### Do not forget the unique key on AnimatePresence

```tsx
// BAD - no key, exit animation does not trigger
<AnimatePresence>
  {isOpen && <motion.div exit={{ opacity: 0 }} />}
</AnimatePresence>

// GOOD - unique key for each conditional child
<AnimatePresence>
  {isOpen && <motion.div key="modal" exit={{ opacity: 0 }} />}
</AnimatePresence>
```

### Do not wrap an already animated component with motion.div

```tsx
// BAD - double animation, transform conflicts
<motion.div animate={{ x: 100 }}>
  <motion.div animate={{ x: -50 }}>Content</motion.div>
</motion.div>

// GOOD - single animation level per transform axis
<motion.div animate={{ x: 100 }}>
  <motion.div animate={{ opacity: 0.5 }}>Content</motion.div>
</motion.div>

// GOOD - use variants to coordinate parent/child
<motion.div variants={parent} animate="active">
  <motion.div variants={child} />
</motion.div>
```

© AThevon · MIT · AThevon/genjutsu

Similar skills

Everything for Frontend and UI →

framer-motion by other authors comes first.

framer-motion Mindrally Tells your agent which properties to animate in Motion and which ones wreck layout. Useful when the project already runs React and TypeScript. CX Codex +1 3,000installs framer-motion pproenca Optimizes React animations using Framer Motion guidelines: slashes bundle size, eliminates unnecessary re-renders, and polishes gesture or scroll transitions. CX Codex +1 1,100installs framer-motion dylantarre This skill guides the agent in implementing Disney's 12 animation principles with Framer Motion in React. Useful for building UI transitions and gesture animations. CX Codex +1 1,700installs motion-framer freshtechbro Guides an agent through Motion and Framer Motion animations for React interfaces, from hover effects to state and layout transitions. CX Codex +1 5,900installs framer-motion-animator patricio0312rev Generates smooth Framer Motion animations and micro-interactions in React. Useful for building page transitions, drag gestures, and scroll effects. CX Codex +1 11,100installs framer-motion-scroll C-Jeril A Framer Motion skill that tells your agent how to build scroll-linked animations, parallax and progress indicators. CX Codex +1 803installs framer-motion-gestures C-Jeril A skill covering Framer Motion gesture animations: drag, pan, tap, hover and focus. Useful when you build interactive elements and need the prop details at hand. CX Codex +1 766installs motion secondsky A skill that feeds your agent the Motion (Framer Motion) docs for React: drag-and-drop, scroll effects, layout transitions. Useful when the agent guesses at props. CX Codex +1 1,100installs review-animations emilkowalski Reviews UI animation and motion code against Emil Kowalski's design standards. Flags slow easings, non-GPU properties, and unnecessary transitions. CX Codex +1 256,500installs

From the same set17

threejs-r3f A skill covering Three.js and React Three Fiber: scene setup, hooks, postprocessing and performance rules. Useful when your agent writes 3D in React. CX Codex +1 1,000installs css-native A skill that tells your coding agent when plain CSS is enough for animations and visual effects, and when to reach for a library. CX Codex +1 1,100installs gsap This skill helps an agent write GSAP animations with timelines, staggered effects, and ScrollTrigger. Use it for complex motion and scroll-linked scenes. CX Codex +1 997installs canvas-generative A skill for algorithmic graphics on Canvas 2D: particles, flow fields, noise, fractals and L-systems. Useful when you need a browser animation or a generative still. CX Codex +1 995installs desktop-principles A skill with desktop UX rules: hover states, pointer precision, keyboard shortcuts, multi-window patterns. Useful when the interface targets macOS, Windows or Linux. CX Codex +1 982installs mobile-principles A rule set for mobile interfaces: tap target sizes, no-hover doctrine, thumb zones, safe areas and gestures. Loads when the agent detects a mobile platform. CX Codex +1 974installs compose-multiplatform Provides Compose Multiplatform patterns for Android, iOS, Desktop, and Web. It guides UI architecture and platform interop via expect and actual declarations. CX Codex +1 951installs swiftui-motion Provides SwiftUI animation rules and decision trees for coding agents. Helps configure springs, phase animators, and clean transitions without visual bugs. CX Codex +1 943installs

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor