Lottie plays exported JSON; Rive runs state machines with data binding. Rive files are typically 10–15× smaller. Choose by interactivity, not just size.
The first eight chapters animated the DOM ourselves. Here the animation is authored in a
design tool and shipped as a file the runtime plays back. Two formats own this space — Lottie and Rive — and the real choice between them isn't
"interactive vs static." It's playback vs systems.
Two philosophies
Lottie is a JSON description of a timeline. An animator builds it in After
Effects (exported with Bodymovin) or in Lottie Creator, and a player such as lottie-web walks that timeline frame by frame. Interactivity, historically, means
controlling playback: which segment plays, how fast, which direction. (dotLottie added
runtime State Machines in late 2025, narrowing the gap.)
Rive ships a binary .riv driven by a single C++ runtime with GPU
rendering. Its differentiator is the state machine: named inputs (booleans, numbers, triggers) flow into states with transitions between them, and data binding (View Models, April 2025) wires those to your
app's state. The file doesn't just play — it responds.
Demo 1 — Lottie: playback control
This circle is a hand-authored bodymovin JSON (scale + rotate keyframes), rendered by lottie-web from an inline animationData object — no network. The
controls below are Lottie's whole interactivity story: play/pause, setSpeed, setDirection, playSegments, goToAndStop.
lottie-web playbacklive demo
loading lottie-web…
JSON size924 bytesthe entire animation, as text
Demo 2 — Rive: the state-machine model
Rive's power is hard to feel without a .riv asset, and we ship none here. So this is
a state-machine concept demo — simulated in plain Svelte/Canvas: the same
building blocks Rive's editor produces. Two inputs (a boolean Power and a
number Charge) drive four states through transitions. Toggle and
drag, and watch the active node in the graph move.
state-machine concept demo (simulated — real Rive loads a .riv)live demo
state: Idle· asleep
hover + click the orb (click = Power toggle)
INPUTS
STATE GRAPH
Idle
Hover
Active
Overload
!Power → Idle
Charge ≥ 90 → Overload
hover → Hover
else → Active
Choosing between them
The decision matrix. Read the last row first — it's the one that usually decides.
Lottie
Rive
Format
JSON (text) — .json / .lottie (zipped)
Binary .riv
Runtime model
Plays a baked, pre-rendered timeline
Runs a live state machine + data binding
Interactivity
Playback control (segments, speed, direction); State Machines via dotLottie (late 2025)
Native: inputs → states → transitions; View Models (Apr 2025)
Data-bound interactive components, characters, games
Playground — author a Lottie by hand
lottie-web is loaded from esm.sh. The animation is a tiny inline
bodymovin object — edit the keyframe k arrays (opacity, rotation), tweak setSpeed, or uncomment setDirection / playSegments to feel
the playback model directly. The byte readout prints below the box.