Fundamentals 14 min read

Unveiling Flutter Desktop: Engine Architecture, Embedder API, and Resize Handling

This article examines the evolution, architecture, and key differences of FlutterEngine on desktop versus mobile, focusing on the Embedder API, platform integration layers, and the challenges of window resize management, providing a comprehensive guide for developers tackling Flutter desktop integration.

Alibaba Terminal Technology
Alibaba Terminal Technology
Alibaba Terminal Technology
Unveiling Flutter Desktop: Engine Architecture, Embedder API, and Resize Handling

1 Introduction

During the implementation of DingTalk's Flutter desktop client we encountered many issues that the official Flutter documentation could not solve, such as integration mode, memory leaks, stutters, and cursor focus anomalies. Because official resources were insufficient, we analyzed source code and design documents to find solutions.

Scarcity of desktop‑related material in the Flutter ecosystem . Official documents provide only high‑level overviews and lack detailed design information; most discussions focus on mobile.

Significant differences between FlutterEngine's mobile and desktop embedder layers . Mobile solutions cannot be directly applied to desktop.

We therefore compiled a Flutter desktop resource collection to lower the learning curve and serve as a technical reference for future engine modifications.

2 Development Timeline

Although Flutter aims to be a cross‑platform UI toolkit, the Flutter Desktop project was initially developed separately from the main Flutter repository. Early development occurred under the flutter‑desktop‑embedding Git project and the "Desktop Embedding for Flutter" discussion group. By analyzing commit history we derived a timeline of Flutter Desktop's evolution.

3 Architecture Comparison

Flutter desktop differs from mobile in two main aspects:

Whether the Embedder API is used.

How Windows resize events are handled.

3.1 Embedder API

The most authoritative source on Flutter architecture is the official documentation.

Note: Web platform differences are omitted because DingTalk does not use Web.

Both mobile and desktop share the Framework (Dart) and Engine (C++) layers; the main divergence lies in the Platform integration layer.

The desktop implementation builds on the Embedder API, providing a set of platform‑agnostic interfaces that encapsulate FlutterEngine as a platform‑independent graphics window toolkit.

The Embedder API sits at the same level as Android and iOS within Flutter's architecture, adding an extra layer for desktop.

Viewing the architecture from a platform‑integration perspective reveals the following hierarchy:

Shell – core platform‑independent implementation (Dart Runtime, Skia, etc.).

Embedder API – platform‑agnostic interface layer that simplifies integration.

Platform‑specific embedder (Android/iOS/macOS/Windows) – injects rendering canvas, thread management, plugin mechanisms.

Platform‑specific interface – the public API exposed to developers.

3.2 Desktop Resize

Beyond the additional Embedder API layer, desktop adds a module for managing window size changes: FlutterResizeSynchronizer .

Relevant design documents include:

How to handle resize in desktop embeddings

Handling flutter view resizing on macOS

Support double buffering for window resizing

In short, asynchronous rendering threads and main‑thread window changes can cause crashes or visual artifacts; FlutterResizeSynchronizer addresses these issues.

4 Implementation Analysis

Using the macOS embedder as an example, we compare Flutter desktop integration with iOS for clarity.

4.1 Class Diagram

The following diagram summarizes core classes of FlutterEngine on macOS.

For comparison, the iOS class diagram is shown below.

Key observations:

Desktop adds an extra cross‑platform Embedder API layer, increasing architectural complexity due to multiple rendering modes and layer composition.

Desktop Resize is primarily controlled by FlutterView , which has a richer role than its thin mobile counterpart.

The Shell layer provides strong abstraction, allowing most scenarios to remain platform‑agnostic.

4.2 Process Comparison

Flutter rendering consists of two stages: UI thread (Dart Framework) and CPU thread (C++ Engine). The second stage differs between iOS and macOS.

Stage 5–6 corresponds to the Desktop Resize control module, involving FlutterView , FlutterResizeSynchronizer , FlutterResizableBackingStoreProvider , and FlutterSurfaceManager . Mobile platforms do not have this flow because they lack window size changes.

Consequences of window size changes during rendering:

If the window changes, the change must wait for the rendering process to finish, potentially causing native thread stalls.

If Flutter rendering occurs during a window change, rendering is delayed until the resize completes, affecting animations.

In DingTalk's desktop rollout we encountered stutters during page creation caused by this synchronization rule and mitigated them by minimizing window changes.

5 Conclusion

This article traced the development of FlutterEngine for desktop and dissected its core architecture.

Flutter Desktop originally leveraged the Embedder API to lower integration costs, but as features grew the multi‑layered design introduced significant complexity. Modifying any core feature now requires coordinated changes across Platform, Embedder, and Shell layers, making the Embedder layer increasingly heavyweight.

For example, the FlutterEngineInitialize function alone spans about 460 lines, with 80 lines dedicated to argument validation, a FlutterProjectArgs struct containing 34 members, and a FlutterRenderConfig struct covering four rendering modes with over ten members each, plus numerous callback pointers.

While it remains uncertain whether future Flutter Desktop will continue to rely on the Embedder API, the current expansion cost appears to outweigh the encapsulation benefits.

Future work will further analyze core desktop processes and aim to align missing mobile capabilities with desktop, benefiting both DingTalk and the broader Flutter ecosystem.

References

flutter‑desktop‑embedding: https://github.com/google/flutter-desktop-embedding

Desktop Embedding for Flutter: https://groups.google.com/g/flutter-desktop-embedding-dev

Flutter architectural overview: https://docs.flutter.dev/resources/architectural-overview

Commit example: https://github.com/google/flutter-desktop-embedding/commit/1940026b543a94f1bc791b1f21052d63522013b9

Embedder API documentation: https://github.com/flutter/flutter/wiki/Custom-Flutter-Engine-Embedders

How to handle resize in desktop embeddings: https://docs.google.com/document/d/1OTy-qCGdP7tYfrEKCNX9A24sgnx5vshfK6FupfniyxA/edit#

Handling flutter view resizing on macOS: https://docs.google.com/document/d/1slGllp1Jhde7wkF6snqGhdrZwHV1VVmXeIF3f0t24JU/edit#

Support double buffering for window resizing: https://docs.google.com/document/d/1allwMZXgX9gGVPguFy3-XydjXEIJgYR1Uhz8Vhm9Rrs/edit#

FlutterDesktopEngineEmbedder APIResize Handling
Alibaba Terminal Technology
Written by

Alibaba Terminal Technology

Official public account of Alibaba Terminal

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.