Back to News/The Future of Flutter: Impeller & Beyond

The Future of Flutter: Impeller & Beyond

Faisal Affan
10/24/2025
The Future of Flutter: Impeller & Beyond

[!NOTE] Impeller is now the default rendering engine on iOS for Flutter 3.10+ and is available for preview on Android.

The Problem: Early-Onset Jank

For years, Flutter developers have battled a specific kind of performance issue known as "shader compilation jank." This occurred because the Skia graphics engine (which Flutter used previously) compiled shaders just-in-time (JIT) as they were needed. If an animation required a complex shader that hadn't been seen before, the frame would drop while the GPU driver compiled it.

This led to the dreaded first-run jank: animations would stutter the first time they played, but run smoothly afterwards.

Enter Impeller: A Radical Shift

Impeller is a complete rewrite of Flutter's rendering layer. Unlike Skia, Impeller leans heavily into Ahead-Of-Time (AOT) compilation for shaders. Instead of compiling shaders on the device during runtime, Impeller compiles all necessary shaders at build time.

Core Philosophy

  1. Predictable Performance: By moving expensive compilation to build time, runtime performance becomes consistent. No more surprise frame drops.
  2. Instrumentation: Impeller is built with modern graphics APIs (Metal and Vulkan) in mind, allowing for deep profiling and debugging.
  3. Portability: While currently focused on mobile, Impeller's architecture is designed to be platform-agnostic at its core.

Deep Dive: How It Works

Impeller replaces the Skia rendering backend with a custom-built renderer tailored specifically for Flutter's needs.

The Rendering Pipeline

When you run flutter build, the Impeller compiler (impellerc) processes your shaders:

# Conceptual build process
flutter build ios --release --enable-impeller
# -> Compiles Dart code to AOT machine code
# -> Compiles Shaders (.frag, .vert) to SPIR-V -> Metal Shading Language (MSL)

At runtime, the engine simply loads these precompiled binaries.

Architecture Overview

LayerResponsibilityTechnology
FrameworkWidgets, Elements, RenderObjectsDart
EngineCompositing, RasterizationC++
ImpellerGPU Command EncodingMetal / Vulkan
GPUExecutionHardware

Performance Benchmarks

In early tests, Impeller has shown dramatic improvements in worst-case frame times.

99th Percentile Frame Times (iPhone 13)

  • Skia: ~18ms (occasional dropped frames)
  • Impeller: ~4ms (consistent 120Hz)

"The difference is night and day. Complex lottie animations that used to stutter on first load now play instantly." — Senior Flutter Engineer

Migrating to Impeller

iOS Implementation

Impeller is enabled by default on iOS in recent Flutter versions. To verify or force-enable it:

<!-- Info.plist -->
<key>FLTEnableImpeller</key>
<true/>

To disable it (fallback to Skia):

flutter run --no-enable-impeller

Android Preview

On Android, Impeller uses Vulkan. It is currently in preview but becoming stable rapidly. To try it out:

flutter run --enable-impeller

Or add this to your AndroidManifest.xml:

<meta-data
  android:name="io.flutter.embedding.android.EnableImpeller"
  android:value="true" />

Creating Custom Shaders

With Impeller, writing custom shaders in GLSL is fully supported. Here is a simple example of a fragment shader that creates a gradient effect:

// shaders/gradient.frag
#version 460 core

precision mediump float;

#include <flutter/runtime_effect.glsl>

uniform vec2 uSize;
uniform vec4 uColorStart;
uniform vec4 uColorEnd;

out vec4 fragColor;

void main() {
    vec2 uv = FlutterFragCoord().xy / uSize;
    fragColor = mix(uColorStart, uColorEnd, uv.x);
}

You can then load this in your Flutter code:

class GradientShader extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ShaderBuilder(
      assetKey: 'shaders/gradient.frag',
      child: Container(width: 200, height: 200),
      (context, shader, child) {
        return CustomPaint(
          painter: ShaderPainter(shader),
          child: child,
        );
      },
    );
  }
}

Known Limitations & Roadmap

While Impeller is the future, it is still maturing.

  • Android Compatibility: Older Android devices without Vulkan support will fall back to OpenGL (and potentially Skia for now).
  • Memory Usage: Impeller can sometimes use slightly more memory than Skia due to precompiled assets, though optimization is ongoing.
  • Platform Support: Web and Desktop support for Impeller is in early R&D stages.

Conclusion

Impeller is not just an incremental update; it defines the next decade of Flutter development. By solving the jank problem at the root — the compilation model itself — Flutter is positioned to be the premier choice for high-fidelity, high-performance cross-platform applications.

If you haven't tested your app with Impeller yet, now is the time. The smoothness is real.


Related Articles