← Back to blog
·5 min read

Framer Motion Cheat Sheet for Vibe Coders

TL;DR

  • Eight core Framer Motion patterns cover 95% of what AI tools generate: entrance, hover, tap, stagger, exit, scroll, layout, and drag
  • Each pattern maps to a specific prompt phrase — knowing the phrase gets you the exact animation you want
  • AI tools default to basic fades without guidance; motion prompts apply all patterns consistently
Get the prompts →

You're vibe coding — describing what you want and letting Cursor, Claude, or Lovable generate the React code. The output is full of motion.div, variants, whileHover, and spring transitions. But what does it all mean? And more importantly, how do you prompt for the specific pattern you need?

This cheat sheet covers the most common Framer Motion patterns that AI coding tools generate. Each section shows the code your AI tool produces, explains what it does, and tells you how to prompt for it.

Bookmark this page. You'll come back to it every time you're prompting for animations.

Pattern 1: Entrance animation (fade + slide up)

This is the most common animation AI tools generate. An element fades in and slides up from below.

<motion.div
  initial={{ opacity: 0, y: 20 }}
  animate={{ opacity: 1, y: 0 }}
  transition={{ type: "spring", damping: 25, stiffness: 250 }}
>
  Content here
</motion.div>

What it does: The element starts invisible and 20px below its final position, then springs into place.

How to prompt for it: "Add an entrance animation — fade in and slide up with spring physics."

Tune it: Increase y for a more dramatic entrance. Lower damping for more bounce. Raise stiffness for a snappier feel.

Pattern 2: Hover state with lift and shadow

Cards that respond to hover with scale, lift, and shadow elevation.

<motion.div
  whileHover={{
    scale: 1.02,
    y: -4,
    boxShadow: "0 12px 32px rgba(0,0,0,0.12)",
  }}
  transition={{ type: "spring", damping: 20, stiffness: 300 }}
>
  Card content
</motion.div>

What it does: On hover, the card scales up slightly, lifts 4px, and gets a deeper shadow. Spring physics make it feel physical.

How to prompt for it: "Add a hover effect — scale up slightly, lift with y offset, and elevate the box shadow. Use spring transition."

Tune it: scale: 1.04 for buttons (more feedback). y: -2 for subtle, y: -6 for dramatic.

Pattern 3: Tap/press feedback

Button press animation that makes clicks feel physical.

<motion.button
  whileHover={{ scale: 1.04 }}
  whileTap={{ scale: 0.97 }}
  transition={{ type: "spring", damping: 15, stiffness: 400 }}
>
  Click me
</motion.button>

What it does: Button scales up on hover and compresses on click. The spring transition makes it bounce slightly.

How to prompt for it: "Add hover scale and tap press feedback to buttons using spring physics."

Pattern 4: Staggered children

List items that enter one after another with a delay between each.

const container = {
  hidden: {},
  visible: {
    transition: { staggerChildren: 0.06 },
  },
};

const item = {
  hidden: { opacity: 0, y: 15 },
  visible: {
    opacity: 1,
    y: 0,
    transition: { type: "spring", damping: 25, stiffness: 250 },
  },
};

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

What it does: The parent orchestrates timing. Each child waits 60ms after the previous one before animating in. Creates a cascading waterfall effect.

How to prompt for it: "Stagger the list items — each one should fade in and slide up with a small delay between siblings. Use Framer Motion variants."

Tune it: staggerChildren: 0.04 for fast cascade, 0.1 for dramatic reveal.

Pattern 5: Exit animations with AnimatePresence

Elements that animate out when removed from the DOM.

import { AnimatePresence, motion } from "framer-motion";

<AnimatePresence mode="wait">
  {isVisible && (
    <motion.div
      key="panel"
      initial={{ opacity: 0, y: 20 }}
      animate={{ opacity: 1, y: 0 }}
      exit={{ opacity: 0, y: -10 }}
      transition={{ type: "spring", damping: 25, stiffness: 250 }}
    >
      Panel content
    </motion.div>
  )}
</AnimatePresence>

What it does: When isVisible becomes false, the element animates out (fades and slides up) before being removed from the DOM. Without AnimatePresence, React removes it instantly.

How to prompt for it: "Wrap conditional content in AnimatePresence. Add entrance and exit animations — fade and slide. Use mode wait so exit completes before entrance."

This is the pattern AI tools miss most often. If your AI-generated app has elements that pop in and out without transitions, it's because AnimatePresence wasn't included. Always explicitly ask for exit animations.

Pattern 6: Scroll-triggered (whileInView)

Elements that animate when they scroll into the viewport.

<motion.section
  initial={{ opacity: 0, y: 40 }}
  whileInView={{ opacity: 1, y: 0 }}
  viewport={{ once: true, amount: 0.3 }}
  transition={{ type: "spring", damping: 25, stiffness: 200 }}
>
  Section content
</motion.section>

What it does: The section starts invisible. When 30% of it enters the viewport, it fades in and slides up. once: true means it only animates on first appearance, not every time you scroll past.

How to prompt for it: "Add scroll-triggered entrance animations to each section. Trigger once when 30% visible. Fade in and slide up with spring physics."

Pattern 7: Layout animations

Smooth transitions when an element's size or position changes.

<motion.div layout transition={{ type: "spring", damping: 25, stiffness: 250 }}>
  {isExpanded ? <FullContent /> : <Summary />}
</motion.div>

What it does: When the content changes and the div needs to resize or reposition, Framer Motion automatically animates the layout change with spring physics. No manual calculation needed.

How to prompt for it: "Add the layout prop to the container so size changes animate smoothly. Use spring transition."

Pattern 8: Gesture drag

Draggable elements with constraints and snap-back.

<motion.div
  drag="x"
  dragConstraints={{ left: -100, right: 100 }}
  dragElastic={0.2}
  whileDrag={{ scale: 1.05 }}
>
  Drag me
</motion.div>

What it does: The element can be dragged horizontally within a 200px range. dragElastic adds resistance at the edges. It scales up while being dragged for visual feedback.

How to prompt for it: "Make this element draggable on the x axis with constraints and elastic edges. Scale up while dragging."

Quick reference table

PatternKey propsPrompt phrase
Entrance`initial`, `animate`"fade in and slide up"
Hover`whileHover`"hover with scale and lift"
Tap`whileTap`"press feedback on click"
Stagger`variants`, `staggerChildren`"stagger the children"
Exit`AnimatePresence`, `exit`"animate out when removed"
Scroll`whileInView`, `viewport`"animate when scrolled into view"
Layout`layout`"animate size/position changes"
Drag`drag`, `dragConstraints`"make it draggable"

What your AI tool is generating under the hood

When you tell Cursor or Claude to "add animations," here's what happens. The AI picks from these patterns based on context. A card grid gets entrance + hover. A modal gets AnimatePresence. A list gets staggered children.

The problem is that without guidance, the AI makes conservative choices — usually just Pattern 1 (basic fade-in) applied everywhere. It skips exit animations, uses linear easing instead of springs, and doesn't stagger.

This is exactly the problem motion prompts solve. A motion prompt tells the AI: "For all entrance animations, use Pattern 1 with these specific spring values. For hover, use Pattern 2. Always include AnimatePresence for conditional elements. Stagger list children by 60ms."

Instead of prompting for each pattern individually, you set the rules once and the AI applies them consistently across every component. See How to Write Animation Prompts for AI Code Tools for a full guide on crafting these prompts.

Tool-specific tips

Cursor: Add your motion specification as a Cursor Rule. Every component generated in Composer or Chat automatically follows your animation patterns.

Claude: Upload the motion prompt as Project Knowledge in Claude or reference it in your CLAUDE.md for Claude Code.

Lovable: Paste the relevant prompt section directly into your Lovable chat alongside your component request.

For best practices on timing and easing values across all patterns, see UI Animation Best Practices for AI-Generated Apps.


Stop guessing what your AI tool needs to hear. UI Motion Prompts encodes all these Framer Motion patterns into structured prompts your AI tool can follow. Every component gets coordinated animations automatically. Browse the library.