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.).

@mkatychev

Copy link
Copy Markdown
Member

Hey @simolus3, is this PR still up for review or are we still waiting on 3.14 changes to land?

@simolus3

simolus3 commented Oct 7, 2026

Copy link
Copy Markdown
Author

Package updates (and ideally a Dart beta) should land before this is merged and haven't yet. I don't think that prevents a review since the content wouldn't change after the release, but I also don't want to waste your time. So if you prefer to wait until everything is ready from mine and Kevin's perspective, that's fine.

@mkatychev

Copy link
Copy Markdown
Member

@vados-cosmonic any thoughts on @simolus3's response? We can start reviewing now and just remove/modify callouts when 3.14 and deps are stable:

> [!WARNING]
> Compiling Dart to non-web WebAssembly targets is experimental.
> This guide requires Dart version `3.14.0-251.0.dev` or later.

@vados-cosmonic

Copy link
Copy Markdown
Collaborator

Hey @mkatychev @simolus3 yeah I think that makes sense -- we'll go ahead and do a review so that we're unblocked when we are ready to merge once stuff lands upstream.

I'll get to this today!

@vados-cosmonic vados-cosmonic left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great start, thanks @simolus3 -- did an initial review and left some thoughts!


This guide walks through building a Dart component that implements
the `adder` world defined in the [`adder/world.wit` package][docs-adder].
The component will implement the `adder` world, which contains an `add` interface with an `add` function.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: I think just pasting the WIT here (we can use a reference so the file stays in sync) would be easier than reading through this prose.

If you still have questions, feel free to open an issue on [the repository][wasm_tools]
or reach out on [Zulip][chat].

## 1. Create your Dart project

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to include a section about tooling/setup here, and that would be a good place for the warning to go

cd dart_wasm_adder
```

## 2. Install the tools

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## 2. Install the tools
## 2. Install Dart tooling for Wasm

Something like this?


## 2. Install the tools

All tools requires to create WebAssembly components from Dart can be installed via pub:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
All tools requires to create WebAssembly components from Dart can be installed via pub:
All tools required to create WebAssembly components from Dart can be installed via `dart pub`:

Maybe it's more normal to refer to it as just "pub", but in that case I think even pub nicely indicates that it's a command/binary of some sort.

dart run wasm_tools witgen -i adder.wit
```

This generates:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be a good place to maybe add a blub about what witgen does as a part of wasm_tools

It might also be nice if where we introduce wasm_tools we add an admonition that notes the difference/contrast to @bytecodealliance/wasm-tools.

```sh
wasmtime run bin/dart_wasm_cli.wasm
```

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: Expected output might be nice to include here

```

To configure this package for WebAssembly components, add tooling dependencies.
Additionally, the `wasi` package provides generated bindings to WASI definitions,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Additionally, the `wasi` package provides generated bindings to WASI definitions,
Additionally, the `wasi` package provides generated bindings to WASI definitions (in this case, `wasi:http`),

Same note about this callout being in the "Writing the HTTP Handler" section


## Importing an interface

The world file (`wit/world.wit`) we generated doesn't specify any imports.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: We might do well to link to the previous guide page here -- my first thought might be "which world WIT that we already generated?"


### Calling the import from Dart

Now the declaration of `add` in the adder's WIT file is visible as an import when

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Now the declaration of `add` in the adder's WIT file is visible as an import when
Because the `calculator` world imports the `add` interface, the declaration of `add` in the adder's WIT file is visible as an import when


### Fulfilling the import

When you build this using `dart run wasm_tools compile`, the `add` interface remains unsatisfied

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
When you build this using `dart run wasm_tools compile`, the `add` interface remains unsatisfied
After building a component with `dart run wasm_tools compile`, the `add` interface remains unsatisfied

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.

4 participants