flutter / flutter/flutter

[meta] Remaining work to unify CanvasKit and Skwasm backends

Open
#175,624 2 comments 3 reactions 1 assignee Claimed by @harryterkelsen View on GitHub
e: web_canvaskit e: web_skwasm P1 team-web
Dominant language
Dart
Stars
179k
Forks
31.1k
PR merge metrics
PR metrics pending

Description

Design: https://github.com/flutter/flutter/issues/171810

This is a meta-issue to track the progress of unifying the Flutter web rendering backends. The goal of this effort is to reduce code duplication, improve maintainability, and create a more flexible architecture that allows rendering strategies to be shared between backends.

The Flutter web engine currently supports two high-performance rendering backends: CanvasKit and Skwasm. While they use different underlying technologies to interact with Skia (JS Interop vs. Wasm FFI), their high-level responsibilities are identical. An analysis of the codebase reveals significant duplication of logic, structure, and boilerplate across both implementations.

This effort will be broken down into the following sub-tasks:

* Unify Surfaces to Share Rasterizers: Refactor the Surface classes to implement a common, DOM-agnostic `EngineSurface` interface focused solely on rasterizing a `ui.Picture`. Move all DOM element creation and management responsibilities into the rasterizer implementations (e.g., `MultiSurfaceRasterizer`), allowing them to be shared across both CanvasKit and Skwasm backends.

* Centralize Native Memory Management: Migrate the CanvasKit backend from the legacy JavaScript `FinalizationRegistry` to Dart's `Finalizer`. This enables the creation of a single, generic `NativeResourceManager` to handle the lifecycle of native objects for both backends, configured with a backend-specific deletion function.

* Share Core `dart:ui` Primitives: Reduce code duplication in primitives like `Canvas`, `Paint`, and `Path` by extracting common logic into a shared base class or composition layer. Backend-specific implementations (Ck... and Skwasm...) will then only handle the final native call, inheriting the shared validation, type conversion, and lifecycle management logic.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.