Comparison
Framer Motion is excellent for React component animations. For scroll-driven effects specifically, svg-scroll-draw does more — at roughly a third of the bytes — and works in any framework.
01
Minified + gzipped. Framer Motion tree-shaking helps but scroll-specific APIs pull in most of the core.
02
Framer Motion
import { motion, useInView } from 'framer-motion';
import { useRef } from 'react';
function Card() {
const ref = useRef(null);
const inView = useInView(ref, { once: true });
return (
<motion.div
ref={ref}
initial={{ opacity: 0, y: 32 }}
animate={inView
? { opacity: 1, y: 0 }
: { opacity: 0, y: 32 }}
transition={{ duration: 0.6, ease: 'easeOut' }}
>
Content
</motion.div>
);
}svg-scroll-draw
import { scrollReveal }
from 'svg-scroll-draw/reveal';
// Works in React, Vue, Svelte,
// Solid, Astro, Nuxt, or vanilla
scrollReveal('.card', {
from: { opacity: 0, y: 32 },
easing: 'ease-out',
once: true,
});Framer Motion
import { useScroll, useTransform,
motion } from 'framer-motion';
function Section() {
const { scrollYProgress } = useScroll({
target: ref,
offset: ['start end', 'end start'],
});
const opacity = useTransform(
scrollYProgress, [0, 1], [0, 1]
);
return (
<motion.div style={{ opacity }}>
Content
</motion.div>
);
}svg-scroll-draw
import { scrollAnimate }
from 'svg-scroll-draw';
scrollAnimate('#section', {
props: { opacity: [0, 1] },
trigger: {
start: 'top bottom',
end: 'bottom top',
},
});import { scrollProgress } from 'svg-scroll-draw/progress';
// Set --scroll-progress (0→1) and --scroll-progress-eased on the element
scrollProgress('#hero', { easing: 'ease-in-out' });#hero {
/* Drive CSS animations directly from the scroll variable */
opacity: calc(var(--scroll-progress-eased));
transform: translateY(
calc((1 - var(--scroll-progress-eased)) * 40px)
);
background-size:
calc(100% + var(--scroll-progress) * 20%)
auto;
}03
Framer Motion does do this — its pathLength / pathOffset / pathSpacing props map onto stroke-dasharray and stroke-dashoffset, normalised 0–1. Paired with useScroll it covers the basic draw. What it has no equivalent for is multi-path stagger orchestration and the native CSS fast path.
Framer Motion needs SplitText manually
Framer Motion useTransform can do this but requires boilerplate
Ours is default-on for scrollDraw, scrollAnimate, scrollReveal, scrollCounter, scrollText, scrollVideo, scrollSnap and Cinematic — but scrollHorizontal opts out by design, and scrollPin/scrollProgress have no reduced-motion path. Framer Motion has useReducedMotion() and MotionConfig reducedMotion="user" — good tooling, but opt-in rather than default.
svg-scroll-draw uses animation-timeline: view() when eligible
Framer Motion is React-only
framer-motion 13.1.0 CJS entry, measured 2026-08-14. Its single bundle is 61.6 KB; a tree-shaken ESM import can be well under both — Framer Motion’s real cost depends heavily on how much of it you use.
✓ supported · ✗ not supported · ~ partial
04
Rich React component animations
Hover states, enter/exit transitions, layout animations, drag — Framer Motion's component model shines for interactive UI beyond scroll.
AnimatePresence
Exit animations when components unmount. Genuinely hard to do without Framer Motion's lifecycle integration.
Gesture animations
Drag, pan, tap, hover — Framer Motion's gesture system is unmatched.
Spring physics
Framer Motion's spring/inertia model is more physics-accurate for complex gesture responses.
~10 KB. Framework-agnostic. MIT. Works everywhere Framer Motion doesn't.