Choosing an animation tool
CSS, View Transitions, Motion, GSAP, Lottie, Rive — six engines for different jobs. A guide to matching the tool to the animation, starting from boring.
In one line: before you reach for a library, try the boring CSS answer — a transition or a @keyframes rule covers far more of real-world UI motion than the tooling debates suggest, and it ships zero bytes.
What it is
There is no single "animation tool" for the web; there is a small landscape, and each piece is shaped for a different job:
- Native CSS (
transition,@keyframes) — declarative motion the browser runs for you. - View Transitions API — native, animated transitions between two DOM states, including shared-element morphs.
- Motion (the library formerly known as Framer Motion, plus its vanilla core) — declarative, state-driven animation and gestures for React.
- GSAP — an imperative timeline engine for complex, sequenced, scrubbable choreography.
- Lottie — a player for designer-authored vector animation exported from After Effects as JSON.
- Rive — interactive vector graphics driven by state machines, with a tiny real-time runtime.
The skill isn't mastering all six. It's recognizing which job is in front of you and reaching for the lightest tool that does it.
Why it matters
The wrong choice is expensive in ways that don't show up until later. Pull in a timeline engine to fade a tooltip and you've shipped a runtime dependency for something one line of CSS does on the compositor. Reach for a JavaScript loop where a @keyframes rule would do and you've moved work off the GPU and onto the main thread, where it competes with everything else and can jank on a mid-range phone.
Bundle size compounds: every engine you adopt is code the user downloads, parses, and executes before your animation even starts. Heavier engines also raise the maintenance bill — more API surface to learn, more version churn to track, more ways for an animation to block interaction or shift layout. And the accessibility floor is the same whatever you pick: if your motion ignores prefers-reduced-motion, the tool didn't fail you, the choice to skip the gate did. Matching the engine to the job keeps all of these small.
See it
Tweak it3
Pick what you're building — a hover state, a route change, an animated chart, a scrubbable timeline, an interactive character, a designer's After Effects file — and the panel names the engine that fits, gives a one-line reason, the main tradeoff, and the one case where you'd reach for something else instead.
How it works
Each engine has a job it's genuinely best at. A fair profile of all six:
CSS transitions / keyframes — for state changes and self-contained loops: hovers, toggles, spinners, attention pulses. Strength: native, zero bundle, compositor-accelerated for transform and opacity. Tradeoff: orchestrating and interrupting sequences gets awkward fast, and there's no built-in spring physics.
View Transitions API — for animating between two states of the page, including shared-element morphs across a route change. Strength: native shared-element transitions with very little code. Tradeoff: a newer browser feature, so it needs progressive enhancement and a sensible no-animation fallback.
Motion — for state-driven motion, gestures, and layout animation in React (with a framework-agnostic core too). Strength: declarative API, spring physics, and interruptible gesture handling. Tradeoff: a runtime dependency, and easy to over-animate when CSS would have done.
GSAP — for complex, sequenced, scrubbable choreography and scroll-linked effects. Strength: the best timeline model available, plus ScrollTrigger. Tradeoff: bundle size, and some plugins carry licensing terms — overkill for a single transition.
Lottie — for playing designer-authored vector animation exported from After Effects as JSON. Strength: faithful handoff of motion that would be painful to rebuild by hand. Tradeoff: limited interactivity, and file size grows quickly with complexity.
Rive — for interactive vector graphics driven by state machines: characters, controls, illustrations that respond in real time. Strength: genuine interactivity on a tiny runtime. Tradeoff: you need the Rive editor and an asset pipeline to author the files.
Build it
Start from CSS. The vast majority of UI motion is a state change you can express declaratively, and the browser will run it on the compositor for free:
.button {
/* Animate only transform/opacity so it stays on the compositor (GPU). */
transition: transform 150ms ease, opacity 150ms ease;
}
.button:hover {
transform: translateY(-2px);
}
.button:active {
transform: translateY(0);
}
/* Always honor the user's reduced-motion preference. */
@media (prefers-reduced-motion: reduce) {
.button {
transition: none;
}
}
/*
* Graduate to a library only when you cross a real threshold:
* spring physics, gesture-driven interrupts, or orchestrating many
* elements on a shared timeline — that's the line where Motion or GSAP
* earns its bundle. Below it, this rule is the whole animation.
*/Make it yours
Use the controls beside the demo above to change what you're building, what you're weighing, and show fall-back tip — each change updates the example live.
Experiment in the playground- Step through all six needs and notice how often the answer is not a library — micro-interactions and page transitions both land on native APIs.
- For any pick, read the "instead" note: it names the case where the opposite choice is right, which is usually the real decision you're making.
- Take a real animation from your own product and run it through the matrix. If it lands on CSS, delete the library you were about to add.
Reproduce it with an LLM
Reproduce it with an LLM
You are a front-end architect. I need to build '{a route transition with a shared hero image in a Next.js app}'. Recommend the single most appropriate animation approach from this set — CSS transitions/keyframes, the View Transitions API, Motion (Framer Motion), GSAP, Lottie, or Rive — and justify it in plain language: why it fits this job, the main tradeoff you're accepting, the rough bundle/performance cost, the accessibility considerations (reduced-motion, focus), and one situation where you'd switch to a different tool instead. Be honest about when the boring CSS answer wins. Return a short recommendation brief.
Pitfalls & accessibility
- Animate
transformandopacitywherever you can. Animatingwidth,height,top, orleftforces layout and paint on every frame and is the most common cause of jank — no library makes that cheap.