Skip to content
Blog

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

PlatformEmbedderStatus
Toyota RAV4Custom C embedderProduction
LG webOSCommunity forkExperimental
Raspberry Piflutter-piCommunity
Fuchsiaflutter_runnerGoogle-maintained
Waylandflutter-embedded-linuxCommunity

Tips for Custom Embedders

  1. Start with the community embedderflutter-embedded-linux is well-documented
  2. Use software rendering first — get the pipeline working before adding GPU
  3. Handle platform messages early — plugins need them for initialization
  4. Test on real hardware — emulators don’t catch timing issues
  5. 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.