framer-motion, react-spring, react-three-fiber, and remotion are specialized libraries for adding motion, interactivity, and 3D graphics to React applications. framer-motion is a production-ready motion library focused on declarative animations and gesture handling for DOM elements. react-spring is a physics-based animation library that interpolates values using spring dynamics for natural movement. react-three-fiber is a React renderer for Three.js, enabling 3D scene construction using React components. remotion is a framework for creating videos programmatically using React, allowing developers to render video content from code rather than traditional editing software.
When building modern React applications, motion is no longer just an afterthoughtโit is a core part of the user experience. The ecosystem offers specialized tools for different kinds of motion: DOM-based UI animations, physics-driven interactions, 3D WebGL rendering, and programmatic video generation. framer-motion, react-spring, react-three-fiber, and remotion each solve distinct problems. Let's compare how they handle animation logic, rendering targets, and developer experience.
framer-motion uses a declarative API where you define the "from" and "to" states.
// framer-motion: Declarative animation
import { motion } from "framer-motion";
function Box() {
return (
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
/>
);
}
react-spring uses physics-based springs to interpolate values.
// react-spring: Physics-based animation
import { useSpring, animated } from "@react-spring/web";
function Box() {
const props = useSpring({
from: { opacity: 0, transform: "translateY(20px)" },
to: { opacity: 1, transform: "translateY(0px)" },
config: { tension: 280, friction: 60 }
});
return <animated.div style={props} />;
}
react-three-fiber is a renderer, not just an animation library.
useFrame or external libraries like @react-spring/three.// react-three-fiber: 3D Rendering loop
import { Canvas, useFrame } from "@react-three/fiber";
function RotatingBox() {
const ref = useRef();
useFrame(() => (ref.current.rotation.x += 0.01));
return <mesh ref={ref}><boxGeometry /><meshStandardMaterial /></mesh>;
}
function App() {
return <Canvas><RotatingBox /></Canvas>;
}
remotion renders video frames programmatically.
// remotion: Frame-based video rendering
import { AbsoluteFill, useCurrentFrame } from "remotion";
function Video({ title }) {
const frame = useCurrentFrame();
const opacity = frame / 30; // Fade in over 30 frames
return (
<AbsoluteFill style={{ justifyContent: "center", alignItems: "center" }}>
<h1 style={{ opacity }}>{title}</h1>
</AbsoluteFill>
);
}
The target output defines which library fits your architecture.
framer-motion targets the DOM. It animates HTML/CSS properties directly. It supports SVG and layout animations via layoutId.react-spring targets DOM, SVG, or WebGL. It is universal but often paired with DOM elements or Three.js meshes.react-three-fiber targets WebGL (Canvas). It creates a 3D context. It does not animate HTML elements directly without bridging libraries.remotion targets Video Files. It renders React components into frames that are stitched into a video file (MP4/WebM) via CLI or cloud rendering.// framer-motion: DOM Layout Animation
<motion.div layoutId="card" /> // Morphs between locations
// react-three-fiber: WebGL Mesh
<mesh position={[0, 0, 0]} /> // Renders in Canvas
// remotion: Video Composition
<Composition id="MyVideo" component={Video} durationInFrames={100} />
framer-motion optimizes for UI responsiveness.
// framer-motion: Gesture support
<motion.div drag dragConstraints={{ left: 0, right: 300 }} />
react-spring optimizes for smooth value interpolation.
// react-spring: Mouse tracking
const [props, api] = useSpring(() => ({ xy: [0, 0] }));
const update = useCallback(({ clientX: x, clientY: y }) => api({ xy: [x, y] }), [api]);
react-three-fiber optimizes for 3D scene graph management.
// react-three-fiber: Automatic disposal
// No manual cleanup needed for meshes when unmounting
<mesh geometry={new THREE.BoxGeometry()} />
remotion optimizes for render speed and reproducibility.
// remotion: Preview vs Render
// <Player /> component for browser preview
// CLI command for actual video rendering
Timing models differ significantly between live animation and video generation.
framer-motion uses time-based transitions.
// framer-motion: Time-based
transition={{ duration: 0.8, ease: "easeInOut" }}
react-spring uses value-based interpolation.
// react-spring: Value-based
config: { mass: 1, tension: 170, friction: 26 }
react-three-fiber uses frame-based loops.
useFrame runs on every requestAnimationFrame.// react-three-fiber: Frame loop
useFrame((state, delta) => {
ref.current.rotation.x += delta;
});
remotion uses absolute frame numbers.
useCurrentFrame() returns the current frame index.// remotion: Frame-based
const frame = useCurrentFrame();
const progress = frame / 60; // 2 seconds at 30fps
All four libraries integrate deeply with React, but their ecosystems serve different needs.
framer-motion has a rich set of pre-built variants and works seamlessly with component libraries like Chakra UI or Material UI.react-spring requires more manual setup for complex sequences but offers greater control over interpolation.// framer-motion: Variants
const variants = { hidden: { opacity: 0 }, visible: { opacity: 1 } };
<motion.div variants={variants} />
react-three-fiber has a dedicated ecosystem (@react-three/drei) for loaders, controls, and helpers.framer-motion and react-spring do not handle 3D assets natively.// react-three-fiber: Asset loading
import { useGLTF } from "@react-three/drei";
const { nodes } = useGLTF("/model.glb");
remotion is the only option for generating actual video files from React code.// remotion: CLI Rendering
// npx remotion render src/index.tsx MyVideo out/video.mp4
| Feature | framer-motion | react-spring | react-three-fiber | remotion |
|---|---|---|---|---|
| Primary Target | DOM / HTML | DOM / Values / WebGL | WebGL / 3D Canvas | Video File (MP4/WebM) |
| Animation Model | Declarative (Time-based) | Physics (Spring-based) | Frame Loop (Delta-based) | Frame Index (Deterministic) |
| Interactivity | High (Gestures, Drag) | High (Mouse, Touch) | High (3D Controls) | Low (Preview only) |
| Best For | UI Transitions, Layouts | Natural Motion, Draggables | 3D Scenes, Products | Programmatic Video Creation |
| Learning Curve | Low | Medium | High (WebGL knowledge helps) | Medium |
framer-motion is the standard for UI motion. If you are building a dashboard, landing page, or web app and need elements to fade, slide, or drag, this is the default choice. It balances power with simplicity.
react-spring is the choice for physics. If your interface needs to feel "alive" with bounce, tension, or continuous interpolation that reacts to user velocity, spring physics provide a more organic feel than time-based transitions.
react-three-fiber is the bridge to 3D. If your requirements exceed 2D CSS transforms and require lighting, cameras, or 3D models, this is the only React-native solution that scales to production WebGL applications.
remotion is for video. If your goal is not to animate a website but to generate video assets (like personalized marketing clips or social media posts) using React logic, Remotion transforms your components into renderable video frames.
Final Thought: These libraries are not mutually exclusive. A single application might use framer-motion for UI transitions, react-three-fiber for a 3D hero section, and remotion to generate a promotional video of that same 3D scene. Choose based on the output medium: DOM, Physics, WebGL, or Video.
Choose react-three-fiber when your project involves 3D graphics, WebGL, or immersive experiences within a React application. It is the standard choice for rendering 3D models, handling cameras, lights, and shaders using React's component model. Use this for product configurators, games, or data visualizations that require three-dimensional space rather than 2D DOM manipulation.
Choose framer-motion when you need robust, declarative animations for standard DOM elements with minimal setup. It is ideal for UI interactions like layout transitions, hover effects, and gesture-based controls (drag, swipe) where performance and ease of use are priorities. It excels in production applications requiring reliable SSR support and a rich set of pre-built animation variants.
Choose react-spring if your application requires physics-based animations that feel natural and responsive to user input. It is best suited for complex interactive interfaces where values need to interpolate smoothly based on velocity and tension, such as draggable cards, dynamic modals, or data visualizations that need to react to state changes without rigid timelines.
Choose remotion if your goal is to generate video content programmatically using React components. It is designed for creating marketing videos, social media clips, or dynamic video templates where content changes based on data. Use this when you need to render video files (MP4, WebM) from code rather than animating elements live in the browser for user interaction.
This package has been deprecated, please use @react-three/fiber from now on.