---
name: motion-react-animation
description: "Motion (motion/react) — layout/shared-element transitions, gestures, scroll-linked effects, springs, and exit animations. Production Motion (formerly Framer Motion): the motion/react import path post-rename, motion components with animate/initial/exit and AnimatePresence, layout and layoutId shared-element transitions, gesture props (whileHover/whileTap/whileDrag), useScroll + useTransform for scroll-linked effects, springs via type:\"spring\" and useSpring, variants with staggerChildren, and the hybrid WAAPI engine plus \"use client\" boundaries for React Server Components."
license: MIT
---

# Motion React Pro

Motion React Pro is a focused skill for building production animations with Motion (`motion/react`), the library formerly published as Framer Motion. It helps you reach for the right primitive — declarative `motion` components, shared-element `layoutId` transitions, gesture props, or scroll-linked `useTransform` chains — and get the spring physics, exit timing, and accessibility details correct the first time. It's aimed at React developers who already know JSX but want idiomatic, performant Motion code rather than CSS-keyframe approximations.

## When to use it

- A list reorders, a card expands into a modal, or an item moves between containers and you want the browser to interpolate position/size automatically.
- You need elements to animate *out* on unmount (route changes, dismissed toasts, removed list rows).
- Hover, tap, drag, or focus should drive motion without manual event wiring.
- A header should shrink, a progress bar fill, or a parallax layer move as the user scrolls.

## How it works

The skill writes against the current `motion/react` import path (not the legacy `framer-motion` package). Core pieces it uses:

- `motion.div` / `motion.button` etc. with `initial`, `animate`, `exit`, and `transition`.
- `<AnimatePresence>` wrapping conditionally-rendered children so `exit` runs before removal; `mode="wait"` and `popLayout` where appropriate.
- `layout` for automatic size/position transitions and `layoutId` for shared-element morphs across components.
- Gesture props `whileHover`, `whileTap`, `whileDrag`, `whileFocus`, plus `drag` with `dragConstraints`.
- `useScroll` + `useTransform` (and `useSpring`) for scroll-linked values; `useMotionValue` for imperative values that bypass React re-renders.

## Example

```bash
curl -fsSL --create-dirs -o ~/.claude/skills/motion-react-animation/SKILL.md https://claudeskil.com/skills/motion-react-animation/SKILL.md
npm i motion
```

```tsx
import { motion, AnimatePresence } from "motion/react"

function Toast({ open }: { open: boolean }) {
  return (
    <AnimatePresence>
      {open && (
        <motion.div
          layout
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          exit={{ opacity: 0, y: 20 }}
          transition={{ type: "spring", stiffness: 400, damping: 30 }}
          whileHover={{ scale: 1.03 }}
        >
          Saved
        </motion.div>
      )}
    </AnimatePresence>
  )
}
```

## Tips & gotchas

- `exit` only fires for direct children of `<AnimatePresence>`; give each a stable `key`.
- `transform`/`opacity` animate on the compositor and stay smooth; animating `width`/`height`/`top` does not — prefer `layout` or `scale`.
- For `layoutId` morphs, both source and target must be mounted at the moment of transition; conditionally swapping them is what triggers the morph.
- Wrap scroll values in `useSpring` to smooth jittery `useScroll` output.

## FAQ

**Do I import from `framer-motion` or `motion/react`?** Use `motion/react` — `framer-motion` still works but is the legacy alias of the same codebase.

**Why won't my element animate out?** It must be a keyed direct child of `<AnimatePresence>`, and the conditional must remove it rather than hide it with CSS.

**Does it respect reduced motion?** Yes — guide patterns use `useReducedMotion()` to drop or shorten transitions for users with that OS preference.
