DEV Community

Alex Spinov
Alex Spinov

Posted on

Framer Motion Has a Free Animation Library: Production-Ready React Animations With Simple Declarative API

CSS animations handle basic transitions. But orchestrated sequences, gesture-driven interactions, layout animations, and spring physics? You need a library. GSAP is powerful but imperative. react-spring has a learning curve. CSS keyframes can't do gesture-based animations.

What if React animations were as simple as adding animate props to your JSX?

import { motion } from "framer-motion";

function FadeIn({ children }) {
  return (
    <motion.div
      initial={{ opacity: 0, y: 20 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.5 }}
    >
      {children}
    </motion.div>
  );
}
Enter fullscreen mode Exit fullscreen mode

That's Framer Motion. Declarative animations for React. Spring physics, gestures, layout animations, scroll-triggered effects — all with a clean API.

Core Animations

// Hover and tap
<motion.button
  whileHover={{ scale: 1.05 }}
  whileTap={{ scale: 0.95 }}
  transition={{ type: "spring", stiffness: 400 }}
>
  Click me
</motion.button>

// Drag
<motion.div
  drag
  dragConstraints={{ left: -100, right: 100, top: -100, bottom: 100 }}
  dragElastic={0.2}
/>

// Scroll-triggered
<motion.div
  initial={{ opacity: 0 }}
  whileInView={{ opacity: 1 }}
  viewport={{ once: true }}
/>
Enter fullscreen mode Exit fullscreen mode

Layout Animations

function ExpandableCard({ isOpen }) {
  return (
    <motion.div layout style={{ borderRadius: 20 }}>
      <motion.h2 layout>Title</motion.h2>
      {isOpen && (
        <motion.p
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
        >
          Expanded content appears here with smooth animation
        </motion.p>
      )}
    </motion.div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Just add layout prop. Framer Motion automatically animates between layouts — size, position, and all.

Staggered Lists

const container = { hidden: {}, show: { transition: { staggerChildren: 0.1 } } };
const item = { hidden: { opacity: 0, y: 20 }, show: { opacity: 1, y: 0 } };

function List({ items }) {
  return (
    <motion.ul variants={container} initial="hidden" animate="show">
      {items.map(i => (
        <motion.li key={i.id} variants={item}>{i.name}</motion.li>
      ))}
    </motion.ul>
  );
}
Enter fullscreen mode Exit fullscreen mode

Exit Animations

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

function Notifications({ items }) {
  return (
    <AnimatePresence>
      {items.map(item => (
        <motion.div
          key={item.id}
          initial={{ opacity: 0, height: 0 }}
          animate={{ opacity: 1, height: "auto" }}
          exit={{ opacity: 0, height: 0 }}
        >
          {item.message}
        </motion.div>
      ))}
    </AnimatePresence>
  );
}
Enter fullscreen mode Exit fullscreen mode

AnimatePresence animates components OUT of the DOM — something CSS can't do.

When to Choose Framer Motion

Choose it for: gesture-driven UI, layout animations, page transitions, complex orchestrated sequences.
Skip it for: simple hover effects (CSS is fine), non-React projects, SSR-heavy pages (adds 30KB).

Start here: motion.dev


Need custom data extraction, scraping, or automation? I build tools that collect and process data at scale — 78 actors on Apify Store and 265+ open-source repos. Email me: Spinov001@gmail.com | My Apify Actors

Top comments (0)