Impeller Rendering Engine

Low PriorityAsked in ~40% of mid-level interviews

3 min read

Flutter Internals

Skia (legacy)Impeller (modern default)
Shader compilationAt runtime — first frame using a new shader jittersPrecompiled at build time — no shader-compile jank
Graphics APIOpenGL (deprecated by Apple)Metal (iOS), Vulkan (Android), OpenGL (legacy Android fallback)
Designed forGeneral-purpose 2D graphics (used by Chrome, Android, etc.)Flutter's specific rendering needs
Frame consistencyVariable — worse on first frame with a new shaderMore predictable
Status (as of 2026)Available behind a flag; legacyDefault on iOS (3.16+) and Android (3.27+)

The original Skia path had a long-standing class of bugs known as "shader compilation jank" — the first time the GPU saw a new shader, it took a few ms to compile, causing a visible stutter. Impeller eliminates that entirely.


What changes for app developers

For most code: nothing. The framework hides the engine. The places it can matter:

ScenarioNotes
Custom FragmentShader usageWorks on Impeller, but the build pipeline handles compilation
Heavy use of BackdropFilterGenerally faster on Impeller
Specific paint operations that hit Skia bugsMay render slightly differently — test on both engines
Older devices (Android < 7 without Vulkan)Falls back to OpenGL Impeller path; some perf characteristics differ
Profile/benchmarks made on SkiaRe-run on Impeller — numbers will shift

You can opt out (or in) per-platform via the impeller-enabled flag in Info.plist (iOS) / AndroidManifest.xml (Android), but the default is now the right choice for nearly all apps.


When this question comes up in interviews

Interviewers typically want to know that you:

  • Understand the user-visible problem Impeller solves (shader jank).
  • Know it's not just "newer renderer" but a deliberate API choice (Metal/Vulkan instead of OpenGL).
  • Recognise that your existing Flutter code keeps working — it's an engine swap, not a framework change.

Common mistakes to avoid

❌ "Impeller makes apps faster" — too vague.
✅ "Impeller removes shader compilation jank by precompiling at build time."

❌ Treating Skia as gone for good.
   Skia still ships as a fallback for some edge cases; Impeller doesn't erase it.

❌ Assuming custom shaders break.
   FragmentShader works on Impeller; build pipeline handles the precompilation.

❌ Benchmarking app perf on debug mode.
   Engines differ but DEBUG instrumentation dominates — always measure in profile or release.

❌ Forcing the legacy Skia path "for compatibility" without a real reason.
   The default is Impeller for good reason; opt out only if you've reproduced a specific bug.

Interview follow-ups

  1. What problem did Impeller solve that Skia couldn't? Shader compilation jank. On Skia, the first frame a shader was used, the engine had to compile it at runtime — visible stutter. Impeller precompiles all shaders during the app build, so every frame uses already-compiled GPU code.

  2. Why move from OpenGL to Metal/Vulkan? OpenGL is deprecated on Apple platforms and increasingly legacy on Android. Metal and Vulkan are modern, lower-overhead APIs that give the engine finer control over GPU command submission. Better baseline performance, fewer driver quirks, future-proof.

  3. Is Skia gone for good? Not entirely. Skia still exists in some fallback paths (older Android devices without Vulkan, certain edge cases). But for the user-facing default on supported platforms, Impeller is the engine.

  4. How would you debug a rendering issue that reproduces on Impeller but not Skia? File it as a Flutter engine bug with a minimal reproduction. Until fixed, you can toggle engines via platform manifest flags. In the meantime, work around the specific paint operation — common culprits are exotic BlendModes, certain ImageFilter combinations, or large saveLayer scopes.


How helpful was this content?

Please sign in to rate this article.