# Use motion/react for JS Animations

**MUST** · **ID:** `animations-ibelick-motion-library` · **Category:** animations
**Source:** [@Ibelick](https://www.ui-skills.com/)
**Interactive version:** https://ui-guides-agent-rules.netlify.app/principles/animations-ibelick-motion-library

> MUST: Use motion/react (formerly framer-motion) when JavaScript animation is required. It provides spring physics, gesture support, and exit animations out of the box.

Use motion/react (Framer Motion) for JavaScript-driven animations instead of manual implementations

Note the conditional in the rule: it does not say to reach for a JS animation library, it says which one to use once you have established that JS is required at all. CSS first; JS only when the interaction genuinely needs it (see animations-implementation-preference). When it does, hand-rolling with requestAnimationFrame or direct DOM writes means re-solving interruption, velocity hand-off, spring physics and gesture integration yourself — motion/react handles those, and the alternative is a pile of animations that restart from zero every time the user touches them.

## Bad — do not do this

`animations-ibelick-motion-library-bad`

```tsx
import { useState } from 'react';

export function IbelickMotionLibraryBad() {
  const [x, setX] = useState(0);

  return (
    <div className="space-y-4">
      <div className="flex gap-2">
        <button
          onClick={() => setX((v) => (v ? 0 : 150))}
          className="px-4 py-2 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors"
        >
          Toggle
        </button>
        <button
          onClick={() => setX(Math.random() * 150)}
          className="px-4 py-2 bg-muted rounded-lg hover:bg-muted/80 transition-colors text-sm"
        >
          Random (interrupt!)
        </button>
      </div>
      <div className="h-16 bg-muted/50 rounded-lg relative overflow-hidden">
        <div
          className="absolute top-2 size-12 bg-primary rounded-lg flex items-center justify-center text-primary-foreground text-xs font-medium"
          // BAD: fixed-duration CSS transition, no velocity awareness
          style={{ transform: `translateX(${x}px)`, transition: 'transform 500ms ease' }}
        >
          CSS
        </div>
      </div>
      <p className="text-xs text-destructive">
        Click "Random" rapidly — a fixed 500ms CSS ease lags behind and re-eases from a standstill instead of responding to velocity
      </p>
    </div>
  );
}
```

## Good — do this

`animations-ibelick-motion-library-good`

```tsx
import { useState } from 'react';
import { motion } from 'motion/react';

export function IbelickMotionLibraryGood() {
  const [isActive, setIsActive] = useState(false);
  const [targetX, setTargetX] = useState(0);

  return (
    <div className="space-y-4">
      <div className="flex gap-2">
        <button
          onClick={() => {
            setIsActive((prev) => {
              const nextActive = !prev;
              setTargetX(nextActive ? 150 : 0);
              return nextActive;
            });
          }}
          aria-pressed={isActive}
          className="px-4 py-2 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors"
        >
          Toggle Spring
        </button>
        <button
          onClick={() => setTargetX(Math.random() * 150)}
          className="px-4 py-2 bg-muted rounded-lg hover:bg-muted/80 transition-colors text-sm"
        >
          Random (interrupt!)
        </button>
      </div>
      <div className="h-16 bg-muted/50 rounded-lg relative overflow-hidden">
        <motion.div
          className="absolute top-2 size-12 bg-primary rounded-lg flex items-center justify-center text-primary-foreground text-xs font-medium"
          animate={{ x: targetX }}
          transition={{ type: 'spring', stiffness: 180, damping: 15 }}
        >
          Spring
        </motion.div>
      </div>
      <p className="text-xs text-success">
        Click "Random" rapidly - spring smoothly redirects mid-animation (interruptible)
      </p>
    </div>
  );
}
```

## References

- [ibelick — baseline-ui SKILL.md](https://github.com/ibelick/ui-skills/blob/main/skills/baseline-ui/SKILL.md)
- [Motion Documentation](https://motion.dev/docs/react)
