framer-motion

Expert guidelines for building performant animations with Framer Motion/Motion library in React applications

INSTALLATION
npx skills add https://github.com/mindrally/skills --skill framer-motion
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

Framer Motion / Motion Animation Guidelines

You are an expert in Framer Motion (now Motion), React, and TypeScript. Follow these guidelines when creating animations.

Core Principles

Import from the Correct Package

  • Use import { motion } from "motion/react" for React projects (not "framer-motion" - this is outdated)
  • The library was renamed from Framer Motion to Motion
  • Always use the latest Motion API

Performance-First Approach

  • Animate transform properties (x, y, scale, rotate) and opacity for best performance
  • These properties can be hardware-accelerated and don't trigger layout recalculations
  • Avoid animating properties that cause layout shifts like width, height, top, left, margin, padding

Hardware Acceleration

Use will-change Properly

// When animating transforms

<motion.div

  style={{ willChange: "transform" }}

  animate={{ x: 100, y: 50, scale: 1.2 }}

/>

// When animating other GPU-accelerated properties

<motion.div

  style={{ willChange: "opacity, transform" }}

  animate={{ opacity: 0.5, x: 100 }}

/>

Properties to Add to willChange

  • transform - for x, y, scale, rotate, skew
  • opacity - for opacity animations
  • filter - for blur, brightness, etc.
  • clipPath - for clip-path animations
  • backgroundColor - for background color transitions

Animation Best Practices

Use Variants for Complex Animations

const containerVariants = {

  hidden: { opacity: 0 },

  visible: {

    opacity: 1,

    transition: {

      staggerChildren: 0.1

    }

  }

};

const itemVariants = {

  hidden: { y: 20, opacity: 0 },

  visible: { y: 0, opacity: 1 }

};

Use layoutId for Shared Element Transitions

<motion.div layoutId="shared-element" />

Prefer spring Animations

// Springs feel more natural than duration-based animations

<motion.div

  animate={{ x: 100 }}

  transition={{ type: "spring", stiffness: 300, damping: 30 }}

/>

React Integration

Memoization for Performance

// Memoize animation variants

const variants = useMemo(() => ({

  hidden: { opacity: 0 },

  visible: { opacity: 1 }

}), []);

// Memoize callbacks

const handleAnimationComplete = useCallback(() => {

  // handler logic

}, []);

Avoid Inline Style Objects

// Bad - creates new object on every render

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

// Good - define outside or memoize

const style = { willChange: "transform" };

<motion.div style={style} />

Accessibility

Respect Reduced Motion Preferences

import { useReducedMotion } from "motion/react";

function Component() {

  const shouldReduceMotion = useReducedMotion();

  return (

    <motion.div

      animate={{ x: shouldReduceMotion ? 0 : 100 }}

      transition={{ duration: shouldReduceMotion ? 0 : 0.3 }}

    />

  );

}

Gesture Animations

Use Gesture Props Correctly

<motion.button

  whileHover={{ scale: 1.05 }}

  whileTap={{ scale: 0.95 }}

  transition={{ type: "spring", stiffness: 400, damping: 17 }}

/>

Scroll Animations

Use useScroll for Scroll-Linked Animations

import { useScroll, useTransform, motion } from "motion/react";

function ParallaxComponent() {

  const { scrollYProgress } = useScroll();

  const y = useTransform(scrollYProgress, [0, 1], [0, -100]);

  return <motion.div style={{ y }} />;

}

Exit Animations

Use AnimatePresence for Exit Animations

import { AnimatePresence, motion } from "motion/react";

<AnimatePresence mode="wait">

  {isVisible &#x26;&#x26; (

    <motion.div

      key="modal"

      initial={{ opacity: 0 }}

      animate={{ opacity: 1 }}

      exit={{ opacity: 0 }}

    />

  )}

</AnimatePresence>

Common Patterns

Staggered List Animation

<motion.ul

  initial="hidden"

  animate="visible"

  variants={{

    visible: { transition: { staggerChildren: 0.07 } }

  }}

>

  {items.map((item) => (

    <motion.li

      key={item.id}

      variants={{

        hidden: { opacity: 0, y: 20 },

        visible: { opacity: 1, y: 0 }

      }}

    />

  ))}

</motion.ul>

Page Transitions

const pageTransition = {

  initial: { opacity: 0, x: -20 },

  animate: { opacity: 1, x: 0 },

  exit: { opacity: 0, x: 20 },

  transition: { duration: 0.3 }

};

Performance Debugging

  • Use React DevTools to inspect re-renders
  • Use Chrome DevTools Performance tab to identify animation jank
  • Target 60fps minimum, 120fps on high refresh rate displays
  • Test on actual devices, especially mid-range Android phones
BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card