| name | flutter-animations |
| description | Enterprise Flutter animation skill — Rive + Lottie dual-engine strategy for production mobile apps. Use when adding animations to Flutter, asking about Rive, Lottie, animated UI components, motion design, interactive states, loading indicators, onboarding flows, micro-interactions, character animations, splash screens, empty states, or any animated widget. Load BEFORE writing any Flutter animation code — enforces correct engine choice, architecture patterns, performance constraints, and accessibility. |
| risk | low |
| source | community (adapted for workspace) |
| date_added | 2026-03-15 |
| allowed-tools | Bash, Read, Write, Edit |
| metadata | {"triggers":"animation, Rive, Lottie, animated widget, motion design, loading indicator, onboarding animation, micro-interaction, character animation, splash screen, empty state animation, interactive toggle, progress ring, skeleton loader, confetti, state machine animation","related-skills":"flutter-mobile, mobile-design, riverpod-patterns, ui-standards-tokens, accessibility-audit","domain":"frontend","role":"specialist","scope":"implementation","output-format":"code"} |
| last-reviewed | 2026-03-15 |
Iron Law
RESOLVE ENGINE CHOICE FIRST (Rive vs Lottie) before writing a single line of animation code — use the decision table below. Then read the relevant reference file. Never hardcode asset paths.
Flutter Animations — Rive + Lottie Dual-Engine
Engine Decision (Always resolve first)
| Use Case | Engine | Why |
|---|
| Interactive buttons, toggles, tab bars | Rive | State machines, pointer input |
| Onboarding with user-driven progression | Rive | Inputs map to gestures |
| Progress indicators tied to real data | Rive | Data binding at runtime |
| Auth flows (loading → success → error) | Rive | Multi-state without code branching |
| Games, character animations | Rive | 60fps, blending, bone rigs |
| Splash / intro screens (play-once) | Lottie | AF export, decorative |
| Empty states, "no results" illustrations | Lottie | Designer-owned, static loop |
| Celebration / confetti effects | Lottie | After Effects shine |
| Icon animations (email sent, checkmark) | Lottie | Simple, small JSON |
| Skeleton loaders with fixed timing | Lottie | Predictable, no interaction |
If unsure: "Does this animation need to respond to app state or user input?" Yes → Rive. No → Lottie.
Package Versions
dependencies:
rive: ^0.14.4
lottie: ^3.3.2
Architecture
Never put animation controller logic directly in a screen widget. Use service + widget separation.
lib/
+-- core/
| +-- animations/
| +-- animation_assets.dart # Typed asset path constants
| +-- animation_preloader.dart # Startup preloader (Rive + Lottie)
| +-- animation_service.dart # Unified facade for DI
| +-- rive_controller_factory.dart # State machine controller factory
| +-- lottie_cache_manager.dart # Composition cache singleton
+-- widgets/
| +-- animations/
| +-- rive_widget.dart # Reusable Rive wrapper
| +-- lottie_widget.dart # Reusable Lottie wrappers (loop/once)
| +-- animation_placeholder.dart # Shimmer shown while loading
| +-- safe_animation.dart # Error-boundary animation widget
+-- assets/
+-- rive/ # .riv files (< 500 KB each)
+-- lottie/ # .json / .lottie files (< 300 KB each)