What is Rive? The Developer's Guide to the Rive Animation Format
A developer-focused deep dive into Rive: the .riv format, state machines, runtimes, and how to integrate Rive animations into your production application.
You have probably seen Rive animations in polished apps and wondered how they work. This guide explains Rive from a developer's perspective — what the format actually is, how state machines work in code, what the runtime options are, and what you need to know to ship Rive animations in a production application.
The .riv Format: What's in the File?
A .riv file is a binary container that stores a Rive scene. Unlike Lottie's JSON, .riv is not human-readable, but it is structured and well-documented. At a high level, a .riv file contains:
- Artboards — named canvases, each with a defined width and height. A single .riv file can have multiple artboards; your runtime selects which artboard to render.
- Objects — shapes, paths, bones, images, text, and other elements arranged in the artboard's hierarchy.
- Animations — named timeline sequences that animate properties of objects over time using keyframes and easing curves.
- State Machines — graphs of animation states connected by conditional transitions, with named inputs that external code can set at runtime.
The binary format means .riv files are compact. For the same animation, a .riv file is typically 50–80% smaller than an equivalent Lottie JSON file.
State Machines: The Developer API
State machines are what differentiate Rive from every other animation format, and they are the primary interface between your application code and a Rive animation. Here is how to think about them:
A state machine has:
- States — each state plays one or more animations (or is an empty "any state" or "exit state"). The machine is always in exactly one state at a time.
- Inputs — named values of type Boolean, Number, or Trigger. Your code reads and writes these values. The state machine evaluates conditions on these inputs to decide whether to transition between states.
- Transitions — directed edges between states with conditions (e.g., "when the Boolean input 'isLoading' becomes true, transition from idle to loading"). Transitions have configurable duration and easing.
- Listeners — optional pointer/cursor event listeners that can set inputs automatically in response to mouse hover, click, or enter/exit events, without any JavaScript code.
Reading and Writing Inputs in JavaScript
jscopyimport { Rive, StateMachineInput } from "@rive-app/canvas"; const r = new Rive({ src: "button.riv", canvas: document.getElementById("canvas"), stateMachines: "ButtonState", autoplay: true, onLoad: () => { // Get a reference to the state machine inputs const inputs = r.stateMachineInputs("ButtonState"); // inputs is an array of StateMachineInput objects // Find inputs by name const loadingInput = inputs.find(i => i.name === "loading"); const successInput = inputs.find(i => i.name === "success"); // Drive the state machine from your application document.getElementById("submit").addEventListener("click", async () => { loadingInput.value = true; try { await submitForm(); successInput.value = true; } finally { loadingInput.value = false; } }); }, });
The Rive Runtimes
Rive provides open-source runtimes for all major platforms. They are all based on the same underlying C++ core, which means behavior is consistent across platforms.
Web (JavaScript / WASM)
The web runtime comes in two flavors:
- @rive-app/canvas — the full-featured runtime using a Canvas 2D fallback for environments without WebGL.
- @rive-app/webgl2 — the WebGL2-backed renderer for maximum performance. Required for the advanced renderer features like gradients and clipping.
- @rive-app/react-canvas and @rive-app/react-webgl2 — React wrappers providing
useRive,useStateMachineInput, and other React-specific hooks.
The runtime is approximately 200KB gzipped (it includes a WASM binary for the renderer). This is the main cost of adopting Rive on the web — plan for it in your bundle budget.
iOS (Swift)
The iOS runtime is a Swift package available via Swift Package Manager or CocoaPods. It provides RiveViewModel (an ObservableObject for SwiftUI) and RiveView (a UIView subclass for UIKit). State machine inputs are accessed via the view model.
Android (Kotlin)
The Android runtime is distributed via Maven. It provides RiveAnimationView (a View subclass) and a ViewModel API for state machine control. Works with Compose via a wrapper composable.
Flutter
The Flutter runtime (rive on pub.dev) provides a RiveAnimation widget and controller API. It uses Flutter's own rendering pipeline.
Hosting and Loading .riv Files
.riv files are static assets — host them anywhere you serve static files (CDN, S3, public folder in Next.js, etc.). A few considerations:
- Set
Content-Type: application/octet-stream(or more specifically,application/x-riveif your CDN supports custom MIME types). - Enable GZIP or Brotli compression on your CDN for .riv files — even binary formats compress well, typically 20–40% further reduction.
- For critical above-the-fold animations, add a
<link rel="preload">tag to start loading the .riv file before the JavaScript runtime requests it.
Runtime Property Manipulation
Beyond state machines, Rive's Data Binding feature (available in runtime 0.12+) lets you link text and color properties to runtime values. This is useful for:
- Dark mode: bind fill colors to a theme input that you toggle at runtime
- Dynamic text: show user names, counts, or other data inside Rive animations
- Progress indicators: bind a number input to a progress value and animate it smoothly
Debugging State Machines
The Rive editor has a built-in preview mode that lets you interact with state machine inputs and observe transitions. For debugging in production:
- Log state machine input values when they change — the runtime emits events for state transitions that you can listen to with
onStateChange. - The Rive runtime exposes
r.stateMachineInputs(name)— log all input names and values to verify the state machine is receiving the values you expect.
Getting Rive Icons for Your Project
Building .riv files from scratch requires the Rive editor. But if you need ready-made animated icons — already built with state machines, optimized for file size — you can download them directly from Unicorn Icons.
Use the editor to customize colors before downloading, then follow the React integration guide to add them to your app. The state machine input names for all Unicorn Icons are documented on each icon's page so you know exactly which inputs to drive.
For a comparison with Lottie, see the Rive vs Lottie guide.