Impeller and Smooth Animations: Why Your Flutter Frames Stop Dropping
Offline shader compilation and prebuilt pipeline state are why Impeller kills animation jank — plus where it runs today.
Published on • October 20, 2026
AI Assistant

The classic Flutter jank story — first run of an animation stutters, then it’s smooth — was always a shader compilation problem. Skia compiled shaders at runtime, on the frame that first needed them. Impeller, Flutter’s rendering engine replacement, removes that failure mode by design. Here’s what the docs actually claim, where it runs, and what to do when it doesn’t behave.
Why Impeller exists
The docs state it plainly: Impeller “precompiles a smaller, simpler set of shaders at engine-build time so they don’t compile at runtime.” That one architectural decision is the smooth-animations story. The engine states its objectives as:
- Predictable performance — all shaders and reflection compiled offline at build time, all pipeline state objects built upfront, with explicit caching the engine controls.
- Instrumentable — every graphics resource tagged and labeled; animations can be captured and persisted to disk without hurting per-frame performance.
- Portable — not tied to one client rendering API; shaders are authored once and converted to backend-specific formats.
- Leverages modern graphics APIs — uses, but doesn’t depend on, features in Metal and Vulkan.
- Leverages concurrency — single-frame workloads can be distributed across multiple threads where necessary.
The 2026 roadmap closes the loop on the Android side: the team is “completing the migration to the Impeller renderer” this year, “finally removing the legacy Skia backend on Android 10 and above” to ensure “smooth animations and reducing jank for every user.”
Where it runs today
Per the Impeller docs (current as of Flutter 3.47):
- iOS — the only supported engine. No ability to switch to Skia.
- Android — enabled by default on API 29+. Devices on lower versions or without Vulkan fall back to the legacy OpenGL renderer automatically.
- Web — still uses Skia; Impeller is listed as a possibility for the future.
- macOS, Linux, Windows — enabled by default as of Flutter 3.47, with opt-out slated for removal in a future release.
As of the 3.27 release, Impeller was already the default on iOS and Android API 29+; the desktop defaults in 3.47 complete the picture minus web.
Disabling it when you must
Sometimes you need an escape hatch — a fidelity bug, a device-specific regression. For debugging:
flutter run --no-enable-impeller
For release builds, it’s per-platform config. Android, under <application> in AndroidManifest.xml:
<meta-data
android:name="io.flutter.embedding.android.EnableImpeller"
android:value="false" />
macOS uses FLTEnableImpeller = false in Info.plist; Linux calls fl_dart_project_set_enable_impeller(project, FALSE) in my_application.cc; Windows uses project.set_impeller_switch(flutter::ImpellerSwitch::Disabled) in main.cpp. Treat these as temporary — the docs say the ability to opt out will be removed on desktop platforms in future releases.
What Impeller does and doesn’t fix
Impeller eliminates runtime shader compilation jank, which is the stutter on first render of an effect: a new transition, a complex shadow, an unusual blend. It doesn’t absolve you of the rest of the frame budget. Excessive saveLayer calls, overdrawn BackdropFilters, janky builds from expensive layout, or blocking platform-channel calls will still drop frames — the engine compiling shaders upfront doesn’t help if your UI thread is late.
Profiling workflow doesn’t change either: use the DevTools performance view, and when you do hit a rendering fidelity or performance issue, the team’s ask (from the docs) is specific — prefix the GitHub issue title with [Impeller], include your device and chip information, screenshots or recordings, and an exported performance trace zipped and attached.
Two supporting pages worth bookmarking: Impeller anti-aliasing covers known differences in edge rendering, and the engine repo hosts the Impeller FAQ plus guides on reading GPU frame captures for both Metal and the GL path.
Practical takeaways
- If you’re on Flutter 3.27+ for mobile or 3.47+ for desktop, Impeller is already on. Don’t add flags; remove any lingering legacy ones.
- First-run animation smoothness is solved at the engine level — but sustained 60/120fps is still your widget-tree responsibility.
- Android devices below API 29 or without Vulkan are on the OpenGL fallback, so test on low-end hardware before assuming parity.
- Web remains the outlier on Skia; performance work there still follows the web performance guide, not the Impeller story.