Skip to content
Back to skills

Framer Motion

BSecurity

Framer Motion React animation library skill — declarative animations, gestures, layout transitions, scroll-triggered animations, variants, AnimatePresence, and performance optimization.

  • 4 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 8, 2026
developmenttypescriptgobashreactnextjsnodespringdebugginggitapi

Works with

  • cli
  • api

Security analysis

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

Pro shows the line behind each finding and how to fix it

Scanned September 8, 2026

npx -y skills add MustafaKemal0146/fetih --skill framer-motion --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Framer Motion?

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

Security grade badge for Framer Motion
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/mustafakemal0146-framer-motion/badge)](https://www.skillsdirectory.com/skills/mustafakemal0146-framer-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: framer-motion
description: "Framer Motion React animation library skill — declarative animations, gestures, layout transitions, scroll-triggered animations, variants, AnimatePresence, and performance optimization."
tags: [react, animation, framer-motion, frontend, motion, gestures, layout, scroll, drag, typescript]
triggers:
  - "framer motion"
  - "react animasyon"
  - "declarative animation"
  - "layout animation"
  - "AnimatePresence"
  - "motion.div"
  - "spring animation"
  - "scroll animation"
  - "drag and drop"
  - "gesture"
  - "page transition"
  - "whileHover"
  - "useAnimation"
  - "useMotionValue"
category: creative
adapted_for: fetih
source: framer/motion (npm: framer-motion)
---

# Framer Motion — Declarative React Animation

Framer Motion is a production-ready animation library for React. Simple declarative API, powerful layout animations, gestures, and server-side rendering support.

**Version:** 12.40.0  
**Package:** `framer-motion`  
**License:** MIT

## Installation

```bash
npm install framer-motion
# or
yarn add framer-motion
# or
pnpm add framer-motion
```

## Core Concepts

### 1. The `motion` Component

Every HTML/SVG element becomes animatable by prefixing with `motion.`:

```tsx
import { motion } from "framer-motion"

<motion.div
  animate={{ x: 100, opacity: 1 }}
  initial={{ x: 0, opacity: 0 }}
  transition={{ duration: 0.5 }}
/>
```

### 2. AnimatePresence (Exit Animations)

Wrap components that conditionally render to animate their removal:

```tsx
import { AnimatePresence, motion } from "framer-motion"

<AnimatePresence>
  {isVisible && (
    <motion.div
      initial={{ opacity: 0, scale: 0.8 }}
      animate={{ opacity: 1, scale: 1 }}
      exit={{ opacity: 0, scale: 0.8 }}
      transition={{ duration: 0.3 }}
    >
      Content
    </motion.div>
  )}
</AnimatePresence>
```

### 3. Variants (Reusable Animation States)

Define named animation states for cleaner code:

```tsx
const variants = {
  hidden: { opacity: 0, y: 20 },
  visible: { opacity: 1, y: 0 },
  exit: { opacity: 0, y: -20 }
}

<motion.div
  variants={variants}
  initial="hidden"
  animate="visible"
  exit="exit"
/>
```

### 4. Gestures (Hover, Tap, Drag)

```tsx
<motion.button
  whileHover={{ scale: 1.05 }}
  whileTap={{ scale: 0.95 }}
  transition={{ type: "spring", stiffness: 400, damping: 17 }}
>
  Click Me
</motion.button>

<motion.div
  drag
  dragConstraints={{ left: 0, right: 300, top: 0, bottom: 300 }}
  whileDrag={{ scale: 1.1, boxShadow: "0 10px 30px rgba(0,0,0,0.2)" }}
/>
```

### 5. Layout Animations

Automatically animate layout changes:

```tsx
<motion.div layout>
  {/* Content that changes size/position */}
</motion.div>

// Shared layout animation (morphing between elements)
<motion.div layoutId="shared-element">
  {selected ? <ExpandedView /> : <CompactView />}
</motion.div>
```

### 6. Scroll-Triggered Animations

```tsx
import { useScroll, useTransform, motion } from "framer-motion"

function ParallaxSection() {
  const { scrollYProgress } = useScroll()
  const scale = useTransform(scrollYProgress, [0, 1], [0.8, 1])
  const opacity = useTransform(scrollYProgress, [0, 0.5, 1], [0, 1, 1])

  return <motion.div style={{ scale, opacity }}>Content</motion.div>
}

// Scroll-linked progress bar
function ProgressBar() {
  const { scrollYProgress } = useScroll()
  return <motion.div style={{ scaleX: scrollYProgress, transformOrigin: "left" }} />
}
```

### 7. `whileInView` (Intersection Observer)

Animate elements when they enter the viewport:

```tsx
<motion.div
  initial={{ opacity: 0, y: 40 }}
  whileInView={{ opacity: 1, y: 0 }}
  viewport={{ once: true, margin: "-50px" }}
  transition={{ duration: 0.6 }}
>
  Appears on scroll
</motion.div>
```

## Common Patterns

### Staggered Children

```tsx
const container = {
  hidden: { opacity: 0 },
  visible: {
    opacity: 1,
    transition: { staggerChildren: 0.1, delayChildren: 0.2 }
  }
}

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

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

### Page Transitions (Next.js / React Router)

```tsx
// With Next.js App Router (template.tsx)
import { motion } from "framer-motion"

export default function Template({ children }: { children: React.ReactNode }) {
  return (
    <motion.div
      initial={{ opacity: 0, y: 20 }}
      animate={{ opacity: 1, y: 0 }}
      exit={{ opacity: 0, y: -20 }}
      transition={{ duration: 0.3 }}
    >
      {children}
    </motion.div>
  )
}
```

### Spring Physics

Spring animations feel more natural than duration-based:

```tsx
<motion.div
  animate={{ x: 100 }}
  transition={{
    type: "spring",
    stiffness: 100,   // Spring strength (default: 100)
    damping: 10,      // Resistance (default: 10)
    mass: 1,          // Object weight (default: 1)
    bounce: 0.25      // Bounciness (0-1)
  }}
/>

// Preset springs
transition={{ type: "spring", stiffness: 300, damping: 30 }} // Snappy
transition={{ type: "spring", stiffness: 50, damping: 20 }}  // Bouncy
```

### Keyframes

```tsx
<motion.div
  animate={{
    x: [0, 100, 50, 100, 0],
    scale: [1, 1.2, 0.9, 1.1, 1],
    rotate: [0, 0, 270, 270, 0]
  }}
  transition={{ duration: 2, repeat: Infinity }}
/>
```

## Performance Optimization

### 1. Use `layout="position"` Instead of `layout`

When only position changes (not size):

```tsx
<motion.div layout="position" />
```

### 2. `useReducedMotion`

Respect accessibility preferences:

```tsx
import { useReducedMotion } from "framer-motion"

const shouldReduceMotion = useReducedMotion()

<motion.div
  animate={shouldReduceMotion ? {} : { x: 100 }}
  transition={{ duration: 0.5 }}
/>
```

### 3. Hardware-Accelerated Properties Only

Animate only `transform` and `opacity` for 60fps:
- ✅ `x`, `y`, `scale`, `rotate`, `opacity`
- ❌ `width`, `height`, `top`, `left`, `backgroundColor`

### 4. Lazy Motion (Tree Shaking)

```tsx
import { m } from "framer-motion"  // Smaller bundle

// Use m.div instead of motion.div
<m.div animate={{ opacity: 1 }} />
```

### 5. `will-change` Hint

```tsx
<motion.div style={{ willChange: "transform" }} />
```

## Best Practices

1. **Wrap all animations in `<AnimatePresence>`** for proper exit animations
2. **Use variants** for reusable animation states across components
3. **Prefer spring** over duration-based transitions for natural feel
4. **Set `viewport={{ once: true }}`** on scroll animations to avoid re-triggering
5. **Always provide `exit` prop** when using conditional rendering
6. **Test with `prefers-reduced-motion`** for accessibility
7. **Use `layoutId`** for shared element transitions between pages
8. **Keep animations between 150-400ms** for UI feedback

## Debugging

```tsx
// Visualize layout animations
<motion.div layout layoutRoot />

// Log animation lifecycle
<motion.div
  onAnimationStart={() => console.log("started")}
  onAnimationComplete={() => console.log("completed")}
/>
```

## Common Gotchas

| Issue | Fix |
|-------|-----|
| Layout animation jitter | Add `layoutId` to animating elements |
| Exit animation not playing | Wrap with `<AnimatePresence>` |
| Children not staggering | Put `staggerChildren` on container's `transition` |
| Transform origin off | Set `style={{ originX: 0.5, originY: 0.5 }}` |
| Hover state flickering | Use `whileHover` not CSS `:hover` |

<!--
  ⚔ Bu skill FETIH AI Agent icin gelistirilmistir — https://github.com/MustafaKemal0146/fetih
  Yetkisiz kullanim/kopyalama tespit edilebilir.
  hash: ee743008151ab4a2
-->

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.