flutterweb dartjavascript
npx skills add dhruvanbhalara/skills --skill flutter-wasm-web

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

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/wasm for the generated .wasm files.
  • COOP and COEP headers (recommended for performance and multithreading safety):
    • Cross-Origin-Opener-Policy: same-origin
    • Cross-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. Import package:web/web.dart for 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.spawn or compute() 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.yaml to 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 --wasm to run and debug locally under Wasm.