Skip to content
Back to skills

Set Up Motion

ASecurity

Use when adding animation and transitions to a frontend — uses the native View Transitions API for navigation/layout changes and the Motion library (motion/react, formerly Framer Motion) for component enter/exit/gesture animation, with every animation gated behind prefers-reduced-motion.

  • 5 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 9, 2026
developmentbashreactvuenodeapifrontendperformance

Works with

  • api

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 2 files and shows the line behind each finding

Scanned October 9, 2026

npx -y skills add VelimirMueller/vlm-code-context-mcp --skill set-up-motion --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Set Up Motion?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Set Up Motion
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/velimirmueller-set-up-motion/badge)](https://www.skillsdirectory.com/skills/velimirmueller-set-up-motion)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: set-up-motion
description: Use when adding animation and transitions to a frontend — uses the native View Transitions API for navigation/layout changes and the Motion library (motion/react, formerly Framer Motion) for component enter/exit/gesture animation, with every animation gated behind prefers-reduced-motion.
---

# Set Up Motion

## 1. Audit current state

```bash
grep -E '"(motion|framer-motion|@vueuse/motion)"' package.json 2>/dev/null
grep -rn "startViewTransition\|view-transition-name\|prefers-reduced-motion\|useReducedMotion" src/ 2>/dev/null | head
```

**Prerequisites:** `@/` alias; pairs with `set-up-routing` (route view-transitions) and `configure-accessibility` (reduced-motion is an a11y requirement, not a nicety).

## 2. Decide what to do
- No motion → full setup.
- Animations present but always-on (ignore reduce-motion) → gate them (step 7) — that's an accessibility bug.

## 3. Detect framework
React → **Motion** (`motion/react`). Vue → **`@vueuse/motion`**. The View Transitions API is native (no dependency) and works in both.

## 4. Install
```bash
pnpm add motion          # React (the package was renamed from framer-motion)
# Vue: pnpm add @vueuse/motion
```

## 5. View Transitions for navigation + layout changes

Native, GPU-accelerated, near-zero JS. Wrap any DOM change you want animated:
```ts
// src/utils/withViewTransition.ts
export function withViewTransition(update: () => void) {
  const reduce = matchMedia('(prefers-reduced-motion: reduce)').matches;
  if (reduce || !document.startViewTransition) {
    update();
    return;
  }
  document.startViewTransition(update);
}
```

For routing, let the router drive it: TanStack Router exposes a `viewTransition` option on `<Link>`/navigation; Vue Router pairs with `startViewTransition` in an `afterEach`/`<RouterView>` wrapper. Name shared elements so they morph between routes:
```css
/* the element that persists across routes */
.hero { view-transition-name: hero; }

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
}
```

## 6. Component animation with Motion (React)

```tsx
import { motion, AnimatePresence, useReducedMotion } from 'motion/react';

export function Toast({ open, children }: { open: boolean; children: React.ReactNode }) {
  const reduce = useReducedMotion();
  return (
    <AnimatePresence>
      {open && (
        <motion.div
          initial={reduce ? false : { opacity: 0, y: 8 }}
          animate={{ opacity: 1, y: 0 }}
          exit={reduce ? { opacity: 0 } : { opacity: 0, y: 8 }}
          transition={{ duration: 0.2, ease: 'easeOut' }}
        >
          {children}
        </motion.div>
      )}
    </AnimatePresence>
  );
}
```
`AnimatePresence` is the reason to reach for Motion — it animates **exit**, which CSS can't do on unmount. Vue: `@vueuse/motion`'s `v-motion` directive, or Vue's built-in `<Transition>`/`<TransitionGroup>` for simple enter/exit.

## 7. Gate everything behind reduced motion

Three layers, all required:
- **Motion:** `useReducedMotion()` → skip or simplify (above).
- **Tailwind:** author transitions as `motion-safe:transition` / disable with `motion-reduce:transition-none`.
- **View Transitions:** the `@media (prefers-reduced-motion: reduce)` block (step 5) kills them.

Essential feedback (a spinner) may remain; decorative motion (parallax, large slides) must not.

## 8. Verify
```bash
pnpm dev
```
Animations play normally; with OS "Reduce motion" on, transitions are removed/instant and nothing janks. Check the Performance panel: animated properties stay on the compositor (transform/opacity), no layout thrash.

## References
- ./motion-patterns.md — View-Transitions-vs-Motion, animate-transform-not-layout, reduced-motion, motion-is-feedback, performance budget.
- ../configure-accessibility/SKILL.md — reduced motion as an a11y requirement.
- ../_shared/conventions.md — `@/` alias, `utils/` for the pure `withViewTransition` helper.

Files in this skill

  • SKILL.md4 KB
  • motion-patterns.md3.1 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.