Flutter Web with WebAssembly (Wasm-GC)
Flutter Web supports compilation to WebAssembly (Wasm-GC) for near-native UI rendering performance, smoother animations, and faster load times.
Contents
- Compilation & Deployment
- Modern JS Interop (
dart:js_interopandpackage:web) - Wasm-Specific Limitations & Solutions
- Debugging WebAssembly
Compilation & Deployment
Compile your application to WebAssembly using the Flutter CLI:
flutter build web --wasm
Server Configuration
Wasm-GC requires serving specific files with correct HTTP headers. Ensure your web host (Firebase Hosting, Cloudflare, Vercel, Nginx) includes:
Content-Type: application/wasmfor the generated.wasmfiles.- COOP and COEP headers (recommended for performance and multithreading safety):
Cross-Origin-Opener-Policy: same-originCross-Origin-Embedder-Policy: require-corp
Modern JS Interop (dart:js_interop and package:web)
Wasm-GC compilation strictly prohibits using the legacy dart:html, dart:js, or package:js libraries. You must utilize the standard dart:js_interop and package:web packages.
JS Interop Core Principles
- Do not import
dart:html. Importpackage:web/web.dartfor DOM access. - Use the
@JS()annotation for declaring external JavaScript functions. - Always use Dart JS Types (e.g.,
JSString,JSNumber,JSBool,JSAny,JSObject).
Example: Invoking a JS API
import 'dart:js_interop';
import 'package:web/web.dart';
// Declare external JS API
@JS('console.log')
external void jsConsoleLog(JSAny message);
@JS('localStorage.setItem')
external void jsSetLocalStorage(JSString key, JSString value);
void main() {
// Convert Dart types to JS types
jsConsoleLog('Hello from Wasm-GC!'.toJS);
jsSetLocalStorage('app_mode'.toJS, 'dark'.toJS);
// Accessing the DOM via package:web
final windowEl = window;
jsConsoleLog(windowEl.location.href.toJS);
}
Wasm-Specific Limitations & Solutions
1. No dart:io
- Impact: Filesystem, Socket, and standard HTTP Client wonβt compile.
- Solution: Use
package:http(resolves to browser-native Fetch API) and use IndexedDB or local storage for caching.
2. Isolate/Threading limitations
- Impact: Standard Dart VM isolates do not run in WebAssembly. Calling
Isolate.spawnorcompute()will throw runtime errors on web. - Solution: Use web worker threads via JS Interop if heavy processing is required, or perform computations on the main thread in small chunks.
3. Font and Asset Loading
- Impact: Wasm compilation renders widgets using CanvasKit. Custom fonts must be declared explicitly in
pubspec.yamlto prevent fallback font rendering.
Debugging WebAssembly
- Chrome Developer Tools: Chrome supports debugging Wasm-GC source maps. You can inspect Dart source code directly in the Chrome Sources panel.
- Check Compatibility: Use
flutter run -d chrome --wasmto run and debug locally under Wasm.