Back to skills
SKILL.md
Framer Motion Expert
ASecurityUse when implementing, optimizing, and timing 60fps/120fps framer motion expert animations, transitions, gesture physics, and reduced-motion fallbacks.
- 5 stars
- 0 votes
- 0 copies
- 0 views
- Added September 27, 2026
Works with
Security analysis
100/100npx -y skills add Harmitx7/tribunal-kit --skill framer-motion-expert --agent claude-codeAre you the author of Framer Motion Expert?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/harmitx7-framer-motion-expert)---
name: framer-motion-expert
description: "Use when implementing, optimizing, and timing 60fps/120fps framer motion expert animations, transitions, gesture physics, and reduced-motion fallbacks."
version: 6.0.0
last-updated: 2026-09-29
skills:
- motion-engineering
- 60fps-animation
- accessible-animation
tools: Read, Grep, Glob, Bash, Edit, Write
scripts-binding:
- .agent/scripts/lint_runner.js
- .agent/scripts/verify_all.js
---
# Framer Motion 12+ β Dense Reference
## Mandatory Pre-Flight Context Inspection
Before reading, generating, or refactoring code in the `framer-motion-expert` domain, inspect these 5 critical parameters:
1. **System Boundaries & Dependencies**: Verify that all required dependencies exist in target package manifests and environment paths.
2. **Runtime Context & Platform Invariants**: Confirm target platform constraints (Node.js, Browser, Mobile OS, Edge runtime) before applying APIs.
3. **Execution Guardrails**: Identify potential side-effects, state mutations, and unhandled asynchronous exceptions.
4. **Validation & Type Contracts**: Validate input data schemas and strict type constraints across all module interfaces.
5. **Observability & Proof of Execution**: Ensure execution produces tangible verification signals (terminal output, tests, metrics).
## Activation Boundaries
- **Activate when:** Use when implementing, optimizing, and timing 60fps/120fps framer motion expert animations, transitions, gesture physics, and reduced-motion fallbacks.
- **DO NOT activate when:** The task falls outside the `framer-motion-expert` domain or is managed by a different dedicated specialist agent.
## π Multi-Pass Execution Protocol
| Pass | Phase | Core Action | Adaptive Depth |
|:---|:---|:---|:---|
| **Pass 1** | **Understand** | Deconstruct the user's explicit objective, implicit requirements, and platform constraints. | Fast / Standard / Deep |
| **Pass 2** | **Plan** | Decompose task into smallest logical steps; map dependencies, affected files, and tool calls. | Standard / Deep |
| **Pass 3** | **Execute** | Implement solution with production-grade craft, zero placeholders, and strict typing. | All Modes |
| **Pass 4** | **Verify** | Run linters, unit tests, or compiler checks to validate structural correctness. | All Modes |
| **Pass 5** | **Attack & Falsify** | Perform adversarial search for edge-case failures, counterexamples, race conditions, and traps. | Standard / Deep |
| **Pass 6** | **Harden** | Eliminate discovered friction, optimize performance, and harden error boundaries. | Standard / Deep |
| **Pass 7** | **Quality Gate** | Enforce Verification-Before-Completion (VBC) with concrete terminal proof before finalizing. | All Modes |
---
## π οΈ Technical Architecture & Reference Recipes
## π οΈ Technical Architecture & Reference Recipes
## Hallucination Traps (Read First)
- β `<Motion>` (capital M) β β
`motion.div` (lowercase dot notation)
- β `motion()` wrapper function β β
`motion.div`, `motion.span`, etc.
- β `exitBeforeEnter` prop β β
`mode="wait"` on `<AnimatePresence>` (removed in FM7+)
- β `exit` works without `<AnimatePresence>` β β
REQUIRES AnimatePresence wrapper
- β `<AnimatePresence>` children without unique `key` β β
ALWAYS set `key`
- β `stiffness + damping` AND `duration + bounce` together β β
pick ONE pair
- β `m.div` without `<LazyMotion>` wrapper β β
REQUIRES LazyMotion parent
- β `layout` animations with `domAnimation` feature set β β
requires `domMax`
- β Force-animating `width`/`height`/`top`/`left` β β
use `x`,`y`,`scale`,`opacity` (GPU)
- β `viewport.once` defaults to true β β
defaults to **false** β add `once: true` for entrance anims
---
## Core Primitives
### `motion.X` / Declarative Animation
```tsx
import { motion } from 'framer-motion';
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
transition={{ duration: 0.3, ease: 'easeOut' }}
/>;
```
### Variants (Stagger / Orchestration)
```tsx
const container = {
hidden: {},
visible: { transition: { staggerChildren: 0.08, delayChildren: 0.1 } },
};
const item = {
hidden: { opacity: 0, y: 20, filter: 'blur(4px)' },
visible: { opacity: 1, y: 0, filter: 'blur(0px)', transition: { duration: 0.4 } },
};
<motion.ul variants={container} initial="hidden" animate="visible">
{list.map(e => (
<motion.li key={e.id} variants={item}>
{e.name}
</motion.li>
))}
</motion.ul>;
```
### Transitions
```tsx
// Tween (default)
transition={{ duration: 0.5, ease: "easeInOut", delay: 0.2, repeat: Infinity, repeatType: "reverse" }}
// Spring (physics)
transition={{ type: "spring", stiffness: 300, damping: 20 }} // OR use duration+bounce, not both
transition={{ type: "spring", duration: 0.8, bounce: 0.25 }}
// Per-property
transition={{ x: { type: "spring", stiffness: 300 }, opacity: { duration: 0.2 } }}
```
---
## Gestures
```tsx
// Hover/Tap/Focus
<motion.button
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
whileFocus={{ boxShadow: "0 0 0 3px rgba(66,153,225,0.6)" }}
transition={{ type: "spring", stiffness: 400, damping: 15 }}
/>
// Drag
<motion.div
drag="x" // "x" | "y" | true
dragConstraints={{ left: -100, right: 100 }}
dragElastic={0.2} // 0=hard stop, 1=free
dragMomentum={true}
dragSnapToOrigin
/>
// Scroll-triggered
<motion.div
initial={{ opacity: 0, y: 50 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, amount: 0.3 }} // β once: true is almost always what you want
/>
```
---
## Layout Animations
```tsx
// layout prop β auto-animates position/size changes
<motion.div layout transition={{ type: "spring", stiffness: 200 }}>
{/* layout="position" = only position, layout="size" = only size */}
</motion.div>
// layoutId β shared element transition (morph between renders)
// List thumbnail β expanded modal:
<motion.div key={item.id} layoutId={`card-${item.id}`} /> // in list
<motion.div layoutId={`card-${selectedId}`} className="modal" /> // in modal
// β TRAP: Cross-tree layoutId requires <LayoutGroup> wrapper
import { LayoutGroup } from "framer-motion";
<LayoutGroup><Sidebar /><MainContent /></LayoutGroup>
```
### AnimatePresence
```tsx
<AnimatePresence mode="sync">
{' '}
{/* "sync"|"wait"|"popLayout" */}
{items.map(item => (
<motion.div
key={item.id}
/* β REQUIRED */ initial={{ opacity: 0, height: 0 }}
animate={{ opacity: 1, height: 'auto' }}
exit={{ opacity: 0, height: 0 }}
/>
))}
</AnimatePresence>
// mode="wait" β waits for exit before entering
// initial={false} on AnimatePresence β skip first-render animation
```
---
## Scroll Animations
```tsx
import { useScroll, useTransform } from 'framer-motion';
// Page scroll progress (0β1)
const { scrollYProgress } = useScroll();
const y = useTransform(scrollYProgress, [0, 1], [0, -200]);
const opacity = useTransform(scrollYProgress, [0, 0.5], [1, 0]);
<motion.div style={{ y, opacity }} />;
// Element-scoped scroll
const ref = useRef(null);
const { scrollYProgress } = useScroll({ target: ref, offset: ['start end', 'end start'] });
```
---
## Hooks
### `useAnimate` β Imperative sequences
```tsx
import { useAnimate, stagger } from 'framer-motion';
const [scope, animate] = useAnimate(); // β returns [scope, animate] NOT [ref, controls]
await animate('.item', { opacity: 1 }, { delay: stagger(0.1) });
<div ref={scope}>...</div>;
```
### `useMotionValue` + `useTransform` β No re-renders
```tsx
const x = useMotionValue(0);
const rotateY = useTransform(x, [-200, 200], [-45, 45]);
// β
useMotionValue does NOT trigger React re-renders β key perf advantage over useState
<motion.div style={{ x, rotateY }} drag="x" />;
```
### `useSpring` / `useVelocity`
```tsx
const springX = useSpring(x, { stiffness: 300, damping: 30 });
const xVel = useVelocity(x);
const skewX = useTransform(xVel, [-1000, 0, 1000], [-15, 0, 15]);
```
---
## Performance & Bundle
```tsx
// LazyMotion β ~5KB vs ~30KB full bundle
import { LazyMotion, domAnimation, m } from 'framer-motion';
// domAnimation β 5KB | domMax β 20KB (needed for layout/drag)
<LazyMotion features={domAnimation}>
<m.div animate={{ opacity: 1 }} />
</LazyMotion>;
```
### Accessibility
```tsx
import { useReducedMotion } from 'framer-motion';
const reduce = useReducedMotion();
// opacity/color: always safe | position/scale/rotation: must be disabled when reduce=true
<motion.div
animate={{ x: reduce ? 0 : 100, opacity: 1 }}
transition={{ duration: reduce ? 0 : 0.5 }}
/>;
```
### Rules
- β
Animate: `x`, `y`, `scale`, `rotation`, `opacity` (GPU composited)
- β Never animate: `width`, `height`, `top`, `left`, `padding`, `margin` (causes layout thrashing)
- β
`useMotionValue` for animation-driven values β never `useState`
- β Nest `AnimatePresence` only when necessary β each adds reconciler overhead
- `"use client"` required in Next.js β `motion.div` cannot run in Server Components
## π¨ Edge-Case & Failure Mode Matrix
| Scenario | Risk | Production Mitigation |
|:---|:---|:---|
| **Empty or Null Inputs** | Unhandled exception or unexpected rendering collapse | Enforce fallback guards, optional chaining, and explicit empty state handlers |
| **Network Timeout / Latency** | Hanging operations or duplicate side-effects | Implement bounded abort controllers, exponential backoff, and idempotency keys |
| **Concurrency / Race Conditions** | Stale state overwrite or inconsistent data mutations | Use atomic transactions, mutex locking, or cancel-on-resubmit controls |
| **Invalid Schema / Malformed Payload** | Downstream runtime errors or security injection | Validate boundary payloads with Zod/Pydantic schemas prior to execution |
| **Resource / Memory Saturation** | OOM errors, frame drops, or memory leaks | Clean up listeners, cancel active timers, and enforce pagination/virtualization |
## ποΈ Tribunal Verification & Guardrails
**Active Reviewers:** `frontend-reviewer` Β· `motion-reviewer` Β· `ui-ux-auditor`
**Slash Command:** `/review` or `/tribunal-full`
### π¬ Evidence Standard (Tri-State Verification)
Every finding, audit statement, or completion claim must classify its factual certainty:
- **`[OBSERVED]`**: Directly confirmed in the codebase or verified via executed terminal command.
- **`[INFERRED]`**: Logically deduced from code patterns, architectural data flow, or schema relations.
- **`[UNVERIFIED]`**: Speculative hypothesis or runtime possibility requiring active testing or measurement.
### β
Pre-Flight Self-Audit Checklist
```
β
Does animation maintain 60fps/120fps using transform (translate3d, scale) and opacity?
β
Is optical mass conserved across state interpolations without volume collapse?
β
Is duration capped within micro-interaction budgets (150msβ280ms)?
β
Is prefers-reduced-motion respected with graceful instant fallbacks?
β
Did I prevent layout thrashing and continuous geometry mutations?
```
### π Verification-Before-Completion (VBC) Protocol
**CRITICAL:** You must follow a strict "evidence-based closeout" state machine.
- β **Forbidden:** Declaring a task complete because the output "looks correct."
- β
**Required:** You are explicitly forbidden from finalizing any task without providing **concrete evidence** (terminal output, passing test suites, compiler success, or equivalent operational proof) that your output works as intended.
Attribution
Comments
Loading commentsβ¦