Flutter Embedder Extensibility: Custom Platforms Explained
Deep dive into Flutter embedder extensibility — how to create custom platform embeddings for automotive, embedded, and non-standard environments.
Published on • September 17, 2026
AI Assistant

What Is a Flutter Embedder?
An embedder is the glue layer that connects Flutter’s rendering engine to a host platform. It provides the surface to draw on, the event loop to process input, and the message channels to communicate with native code.
Every supported platform (Android, iOS, web, desktop) has its own embedder implementation. But the embedder API is public, allowing anyone to create new ones.
The Embedder API
The C-based embedder API exposes:
// Core types
typedef struct {} FlutterRendererConfig;
typedef struct {} FlutterProjectArgs;
typedef struct {} FlutterEngine;
// Key functions
FlutterEngineRun(size_t version, const FlutterRendererConfig* config,
const FlutterProjectArgs* args, void* user_data,
FlutterEngine* engine);
FlutterEngineSendWindowMetricsEvent(FlutterEngine engine,
const FlutterWindowMetricsEvent* event);
FlutterEngineSendPlatformMessage(FlutterEngine engine,
const FlutterPlatformMessage* message);
Creating a Custom Embedder
Step 1: Surface Management
Create a rendering surface (OpenGL, Vulkan, or software):
bool create_surface(void* user_data, FlutterRendererConfig* config) {
config->type = kOpenGL;
config->open_gl.struct_size = sizeof(FlutterOpenGLRendererConfig);
config->open_gl.make_current = &make_current;
config->open_gl.clear_current = &clear_current;
config->open_gl.present = &present;
config->open_gl.gl_proc_resolver = &gl_proc_resolver;
return true;
}
Step 2: Event Handling
Forward platform events to Flutter:
void on_mouse_event(double x, double y, FlutterPointerSignalKind kind) {
FlutterPointerEvent event = {};
event.struct_size = sizeof(FlutterPointerEvent);
event.type = kind == kFlutterPointerSignalKindNone
? kFlutterPointerMove
: kFlutterPointerScroll;
event.x = x;
event.y = y;
FlutterEngineSendPointerEvents(engine, &event, 1);
}
Step 3: Platform Messages
Handle method calls from Dart:
void handle_platform_message(const FlutterPlatformMessage* message,
void* user_data) {
// Route messages to your native implementation
if (strcmp(message->channel, "com.myapp/native") == 0) {
process_message(message);
}
}
Real-World Examples
| Platform | Embedder | Status |
|---|---|---|
| Toyota RAV4 | Custom C embedder | Production |
| LG webOS | Community fork | Experimental |
| Raspberry Pi | flutter-pi | Community |
| Fuchsia | flutter_runner | Google-maintained |
| Wayland | flutter-embedded-linux | Community |
Tips for Custom Embedders
- Start with the community embedder —
flutter-embedded-linuxis well-documented - Use software rendering first — get the pipeline working before adding GPU
- Handle platform messages early — plugins need them for initialization
- Test on real hardware — emulators don’t catch timing issues
- Contribute upstream — the Flutter team welcomes embedder PRs
Conclusion
Flutter embedder extensibility is the secret weapon that makes Flutter a universal UI toolkit. With the C API and a graphics surface, you can bring Flutter to literally any platform.