Skip to content

Add Dart documentation - #377

Open
simolus3 wants to merge 1 commit into
bytecodealliance:mainfrom
simolus3:dart
Open

simolus3 wants to merge 1 commit into
bytecodealliance:mainfrom
simolus3:dart

Conversation

@simolus3

Copy link
Copy Markdown

This documents how to create components with the Dart programming language.

Dart compiles to WebAssembly, but has no support for the component model. Instead, it uses Dart-specific set of host imports to implement its functionality. I maintain a toolchain that eliminates these imports by implementing them in plain WebAssembly, and to create WebAssembly components.

This adds Dart pages for functionality that is currently supported (simple components, custom imports, wasi cli and http service).

A lot of this is mildly broken, e.g. this requires a development version of the Dart SDK that hasn't been released yet and my tools are still highly buggy. But this is enough to get components to work, so I think it's worth adding documentation for that.

@kevmoo

kevmoo commented Sep 26, 2026

Copy link
Copy Markdown

Thanks for putting this together, @simolus3! Having Dart covered across all four guides (especially alongside Rust on the HTTP service page!) is awesome.

1. Timing: Hold for Dart 3.14 Beta (Oct 6) + pub.dev Package Publish

I'd recommend holding off on merging this until at least the Dart 3.14 beta drop (targeted for Oct 6) and a fresh pub.dev publish of wasm_tools / wasm_components:

  • SDK constraint: 3.14.0-251.0.dev isn't a downloadable build on the dart-archive dev channel (which currently stops at 3.14.0-248.0.dev, prior to try_table landing in dart-lang/sdk@de942dbb3e5). Waiting for the Oct 6 3.14 beta drop lets the callout banners and pubspec.yaml constraints target a standard beta release (>=3.14.0-0) that includes both try_table and the wasm:import / wasm:export TFA signature fix ([dart2wasm] Is TFA return-type narrowing intended for @pragma('wasm:export') functions? dart-lang/sdk#64356).
  • pub.dev version skew: Right now wasm_tools and wasm_components on pub.dev are still at 0.1.0-preview.0 from June 2026, so running the tutorial commands with dart pub add hits not yet implemented: Instruction: U32FromI32 in witgen, TODO: Input directory on -i ./wit, and missing Option/Owned/StreamVtable types when compiling with wasi 0.1.0-preview.0. Publishing 0.1.1-preview.0 from wasm.dart main will resolve those.

2. E2E Walkthrough Findings (Tested against wasm.dart main + Dart 3.14.0-271.0.dev + wasmtime 49.0.0)

  1. building-a-simple-component/dart.md (✅ Works E2E):

    • Line 14 has a leftover placeholder: or TODO: running a component. -> link to [Creating runnable components](../creating-runnable-components/dart.md).
    • Line 30 typo: All tools requires -> All tools required.
    • Line 62 typo: The JSON file describe -> The JSON file describes.
  2. importing-and-reusing-components/dart.md:

    • Line 8 (wit/world.wit vs adder.wit): Says "The world file (wit/world.wit) we generated doesn't specify any imports", whereas the previous guide created adder.wit in the package root.
    • Missing hook/link.dart update & bin/calculate.dart path: Running dart run wasm_tools witgen -i ./wit -w "docs:calculator/calculator" wipes lib/src/components/ (deleting docs_adder_adder.json and generating docs_calculator_calculator.json). The guide should explicitly tell the reader to save the Dart code in bin/calculate.dart and update hook/link.dart to load lib/src/components/docs_calculator_calculator.json — otherwise wasm_tools compile fails with PathNotFoundException looking for docs_adder_adder.json.
    • wasm-tools component wit ./bin/calculate.wasm validation failure: After updating hook/link.dart, dart run wasm_tools compile bin/calculate.dart --no-implicit-wasi-imports succeeds, but running wasm-tools component wit ./bin/calculate.wasm fails with:
      error: instance not valid to be used as export (at offset 0x23e32)
      Because docs:calculator/calculate@0.1.0 defines a nominal enum (enum op { add }) used in eval-expression's parameter list, the Component Model validator requires the exported instance to also export the type (export "op" (type ...)) before exporting "eval-expression".
  3. creating-runnable-components/dart.md (✅ Works E2E):

    • In Step 1, add cd dart_wasm_cli after dart create -t cli dart_wasm_cli.
  4. using-http-in-components/dart.md:

    • In Step 1, add cd dart_wasm_service after dart create -t cli dart_wasm_service.
    • Stream.value worker trap in wasmtime serve: When serving bin/dart_wasm_service.wasm with wasmtime 49.0.0, curl receives the HTML response, but contents: .some(.value(utf8.encode(responseText))) (Stream.value) immediately causes the worker to trap with Caused by: cannot drop busy stream (StreamSinkState._onDone -> dropWritable), because Stream.value fires onDone synchronously in the same microtask turn before the WASI 0.3 stream write settles.
    • (Minor note): Since wasmtime serve instantiates a fresh component instance per HTTP request, _requestId resets to 0 on every request (This is request number 0 served by this server.).

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants