Skip to content
Blog

Lottie vs Rive in Flutter: Picking an Animation Runtime for Your App

A practical comparison of the lottie and rive Flutter packages: rendering models, APIs, performance trade-offs, and how to choose between After Effects JSON and Rive's interactive state machines.

Published on • October 3, 2026

AI Assistant

Flutter’s built-in animation primitives cover tweens, springs and heroes beautifully — but the moment a designer hands you an After Effects export or an interactive character, you need a runtime that plays authoring-tool files. The two packages that show up in almost every shortlist are lottie and rive.

Sources: lottie on pub.dev, rive on pub.dev.

The two models, in one paragraph each

Lottie renders animations exported from Adobe After Effects with the Bodymovin plugin. The package is a pure Dart port of Lottie-android — it parses the JSON (or .zip/.lottie/Telegram .tgs archives) and draws frames itself, so the same file works on Android, iOS, macOS, Linux, Windows and Web with no native library. The file is the animation: what the motion designer exported is what ships.

Rive is an end-to-end pipeline: a browser-based editor, a stateful .riv graphics format, and a runtime with its own vector renderer. Since Rive 0.14 the Flutter package leans on rive_native, a native library downloaded during build, and lets you choose either the Rive renderer or Flutter’s own renderer (Skia/Impeller) per File.

API feel: one widget vs. a scene graph

Lottie is deliberately tiny:

Lottie.asset('assets/success.json');

Lottie.network(
  'https://assets.example.com/loading.json',
  width: 200, height: 200, fit: BoxFit.fill,
);

Need playback control? Hand it an AnimationController and you get the full Flutter animation toolkit for free — pause, reverse, seek, drive it from a gesture:

Lottie.asset(
  'assets/success.json',
  controller: _controller,
  onLoaded: (composition) {
    _controller
      ..duration = composition.duration
      ..forward();
  },
);

You can also load compositions yourself with AssetLottie(...).load() and draw individual frames with LottieDrawable on a CustomPainter, and override layer properties at runtime through ValueDelegate (text, colour, opacity, position).

Rive’s API is closer to a scene graph: you load a File, pick an artboard, and drive a state machine — Rive’s own interactive graph of states, inputs and transitions — plus data binding. That is the fundamental difference: Lottie plays a timeline, Rive plays a machine.

Feature comparison

lottie 3.6.xrive 0.14.x
Authoring toolAdobe After Effects + BodymovinRive editor (rive.app)
File formatJSON (.json, .zip, .tgs, .lottie).riv
ImplementationPure DartDart API + rive_native
InteractivityTimeline control, ValueDelegate overridesState machines, data binding, widgets
RenderersFlutter’s rendererRive renderer or Flutter renderer
PlatformsAndroid, iOS, Linux, macOS, Windows, WebAndroid, iOS, Linux, macOS, Windows, Web
Size / traction4.5k likes, 2.06M downloads1.9k likes, 461k downloads
LicenseMITMIT

Performance notes worth knowing

  • Lottie’s renderCache (added in v3.0) renders frames lazily into an offscreen cache so subsequent runs are cheaper. It trades memory for CPU/GPU cost — worth enabling for long-running looping animations such as loaders.
  • Frame rate: Lottie plays at the After Effects export rate (often 10 or 30 FPS) by default, which is power-friendly on a 120 Hz phone. Override with frameRate: FrameRate.max when you need buttery motion.
  • Rive renderer choice: File.asset('assets/x.riv', riveFactory: Factory.rive) picks the Rive renderer; Factory.flutter uses Flutter’s. If you see a visual discrepancy on iOS, the Rive docs suggest first re-running with flutter run --no-enable-impeller to check whether it’s an Impeller-specific issue.
  • Native libraries: Rive downloads prebuilt rive_native binaries during flutter run/flutter build; a manual fallback exists (dart run rive_native:setup --verbose --clean --platform macos). On CI, run flutter clean && flutter pub get first if the libraries look stale.

Choosing between them

Reach for Lottie when:

  • Your designers already live in After Effects and hand over .json exports (LottieFiles workflows).
  • The animation is decorative: loaders, success checks, empty states, stickers.
  • You want zero native dependencies and maximum platform reach, including Web with no extra build steps.

Reach for Rive when:

  • The animation must react: menus, toggles, characters that respond to touch or app state.
  • You want state machines instead of hand-wiring playback in Dart.
  • Asset size matters — Rive’s binary format plus state-machine logic usually beats a long JSON timeline.
  • You’re building a game or a highly branded UI and want consistent rendering via Rive’s own renderer.

Many teams end up using both: Lottie for one-off motion assets, Rive for the interactive centerpiece.

Getting started

dependencies:
  lottie: ^3.6.1
  rive: ^0.14.11

Lottie’s example folder (via dart pub unpack lottie) contains samples for controllers, delegates and custom drawing; Rive’s getting-started guide lives at rive.app/docs/runtimes/flutter/flutter. Both packages are MIT-licensed and published by verified publishers (xaha.dev and rive.app).

Whichever you pick, keep animations out of the build path: load them lazily, respect prefers-reduced-motion, and test on a low-end device — motion that looks free on a flagship often isn’t.