From daf21bfa838da2accbc484b21b6147fea792fada Mon Sep 17 00:00:00 2001 From: zihang Date: Wed, 27 Aug 2025 15:17:18 +0800 Subject: [PATCH 1/6] doc(moonbit): add MoonBit explanation --- component-model/src/SUMMARY.md | 1 + component-model/src/introduction.md | 2 + component-model/src/language-support.md | 1 + .../src/language-support/moonbit.md | 357 ++++++++++++++++++ 4 files changed, 361 insertions(+) create mode 100644 component-model/src/language-support/moonbit.md diff --git a/component-model/src/SUMMARY.md b/component-model/src/SUMMARY.md index 3512e3dd..4dc11ece 100644 --- a/component-model/src/SUMMARY.md +++ b/component-model/src/SUMMARY.md @@ -23,6 +23,7 @@ - [JavaScript](./language-support/javascript.md) - [Python](./language-support/python.md) - [Rust](./language-support/rust.md) + - [MoonBit](./language-support/moonbit.md) - [WebAssembly Text Format (WAT)](./language-support/wat.md) - [Other Languages](./language-support/other-languages.md) - [Running Components](./running-components.md) diff --git a/component-model/src/introduction.md b/component-model/src/introduction.md index 1ed749b9..992e4019 100644 --- a/component-model/src/introduction.md +++ b/component-model/src/introduction.md @@ -19,6 +19,7 @@ This documentation is aimed at _users_ of the component model: developers of lib | [Worlds] | [JavaScript] | | | | [Python] | | | | [Rust] | | +| | [MoonBit] | | [Why Components?]: ./design/why-component-model.md [Components]: ./design/components.md @@ -31,6 +32,7 @@ This documentation is aimed at _users_ of the component model: developers of lib [JavaScript]: ./language-support/javascript.md [Python]: ./language-support/python.md [Rust]: ./language-support/rust.md +[MoonBit]: ./language-support/moonbit.md [Composing]: ./composing-and-distributing/composing.md [Running]: ./running-components.md diff --git a/component-model/src/language-support.md b/component-model/src/language-support.md index 07f60781..67e52941 100644 --- a/component-model/src/language-support.md +++ b/component-model/src/language-support.md @@ -37,6 +37,7 @@ without using a higher-level language front-end. - [Rust Tooling](./language-support/rust.md) - [Building a Component with `cargo component`](./language-support/rust.md#building-a-component-with-cargo-component) - [Running a Component from Rust Applications](./language-support/rust.md#running-a-component-from-rust-appliacations) + - [MoonBit Tooling](./language-support/moonbit.md) - [WebAssembly Text Format (WAT)](./language-support/wat.md#wat-webassembly-text-format) - [Building a Component from WAT with `wasm-tools`](./language-support/wat.md#building-a-component-with-wasm-tools) - [Running a Component with Wasmtime](./language-support/wat.md#running-a-component-with-wasmtime) diff --git a/component-model/src/language-support/moonbit.md b/component-model/src/language-support/moonbit.md new file mode 100644 index 00000000..1bd5b878 --- /dev/null +++ b/component-model/src/language-support/moonbit.md @@ -0,0 +1,357 @@ +# MoonBit Tooling + +MoonBit is a programming language that provides first-class support for +WebAssembly . This guide demonstrates how to build WebAssembly components using +MoonBit, leveraging WIT (WebAssembly Interface Types) for interface definitions +and the `wit-bindgen` toolchain for code generation. + +This tutorial walks through building a component that implements the +[`adder` world][adder-wit] defined in the `docs:adder` package. The component +will export an `add` interface containing an `add` function that sums two +numbers. + +[adder-wit]: https://github.com/bytecodealliance/component-docs/tree/main/component-model/examples/tutorial/wit/adder/world.wit + +## 1. Install the Tools + +### Installing MoonBit + +First, install the MoonBit compiler and toolchain. Follow the installation +instructions from the +[MoonBit download page](https://www.moonbitlang.com/download). + +Verify your MoonBit installation (below are the versions at the time of +writing): + +``` +$ moon version +moon 0.1.20250801 (edae1ae 2025-08-01) ~/.moon/bin/moon +moonc v0.6.24+012953835 ~/.moon/bin/moonc +moonrun 0.1.20250801 (edae1ae 2025-08-01) ~/.moon/bin/moonrun +``` + +### Installing `wit-bindgen` + +Install the `wit-bindgen` CLI tool, which generates MoonBit bindings from WIT +files: + +``` +$ cargo install wit-bindgen-cli +``` + +### Installing `wasm-tools` + +Install `wasm-tools` for working with WebAssembly components: + +``` +$ cargo install wasm-tools +``` + +Verify the installations (below are the versions at the time of writing): + +``` +$ wit-bindgen --version +wit-bindgen-cli 0.44.0 (bdb4df54b 2025-08-14) +$ wasm-tools --version +wasm-tools 1.237.0 +``` + +## 2. Define the Interface (WIT) + +Before generating the MoonBit project, you need to define the component +interface using WIT. Create a directory for your project and define the WIT +file: + +```console +$ mkdir moonbit-adder && cd moonbit-adder +$ mkdir wit +``` + +Create `wit/world.wit` with the following content: + +```wit +package docs:adder@0.1.0; + +interface add { + add: func(x: u32, y: u32) -> u32; +} + +world adder { + export add; +} +``` + +This WIT definition: + +- Declares a package `docs:adder` with version `0.1.0` +- Defines an `add` interface with a single function that takes two `u32` + parameters and returns a `u32` +- Creates an `adder` world that exports the `add` interface + +## 3. Generate MoonBit Project Structure + +Use `wit-bindgen` to generate the MoonBit project structure and bindings: + +```console +$ wit-bindgen moonbit wit/world.wit --out-dir . \ + --derive-eq \ + --derive-show \ + --derive-error +``` + +This command generates the following directory structure: + +``` +. +├── ffi +│ ├── moon.pkg.json +│ └── top.mbt +├── gen +│ ├── ffi.mbt +│ ├── gen_interface_docs_adder_add_export.mbt +│ ├── interface +│ │ └── docs +│ │ └── adder +│ │ └── add +│ │ ├── moon.pkg.json +│ │ ├── stub.mbt +│ │ └── top.mbt +│ ├── moon.pkg.json +│ ├── world +│ │ └── adder +│ │ ├── moon.pkg.json +│ │ └── stub.mbt +│ └── world_adder_export.mbt +├── moon.mod.json +├── wit +│ └── world.wit +└── world + └── adder + ├── ffi_import.mbt + ├── import.mbt + ├── moon.pkg.json + └── top.mbt +``` + +The generated files include: + +- `moon.mod.json`: MoonBit module configuration +- `gen/`: Generated export bindings + - `interface/`: Generated export interface bindings + - `world/`: Generated export world bindings + - `stub.mbt`: Main implementation file +- `interface/`: Generated import interface bindings +- `world/`: Generated import world bindings + +## 4. Examine the Generated Code + +The `wit-bindgen` tool generates MoonBit bindings that handle the WebAssembly +component interface. Let's examine the generated +`gen/interface/docs/adder/add/stub.mbt`: + +```moonbit +// Generated by `wit-bindgen` 0.44.0. + +pub fn add(_x : UInt, _y : UInt) -> UInt { + ... +} +``` + +The `...` is the placeholder syntax in MoonBit. When executing +`moon check --target wasm`, 'unfinished code' warnings will appear. + +## 5. Implement the Component Logic + +Now implement the `add` function in `src/lib.mbt`: + +```moonbit +// Generated by `wit-bindgen` 0.44.0. + +///| +pub fn add(x : UInt, y : UInt) -> UInt { + x + y +} +``` + +## 6. Configure the Build + +Ensure your `gen/moon.pkg.json` is properly configured for WebAssembly target: + +```json +{ + // link configuration for Wasm backend + "link": { + "wasm": { + "exports": [ + // Export for cabi_realloc + "cabi_realloc:cabi_realloc", + // Export per the interface definition + "wasmExportAdd:docs:adder/add@0.1.0#add" + ], + "export-memory-name": "memory", + "heap-start-address": 16 + } + }, + "import": [ + { + "path": "docs/adder/ffi", + "alias": "ffi" + }, + { + "path": "docs/adder/gen/interface/docs/adder/add", + "alias": "add" + } + ] +} +``` + +## 7. Build the WebAssembly Component + +Build the MoonBit code to WebAssembly: + +```console +$ moon build --target wasm +``` + +This generates a WebAssembly module. To create a proper WebAssembly component, +use `wasm-tools`: + +```console +$ wasm-tools component embed wit target/wasm/release/build/gen/gen.wasm \ + --encoding utf16 \ + --output adder.wasm +$ wasm-tools component new adder.wasm --output adder.component.wasm +``` + +You can verify the component's interface using `wasm-tools`: + +```console +$ wasm-tools component wit adder.component.wasm +``` + +Expected output for both commands: + +```wit +package root:component; + +world root { + export docs:adder/add@0.1.0; +} +package docs:adder@0.1.0 { + interface add { + add: func(x: u32, y: u32) -> u32; + } +} +``` + +## 8. Testing the Component + +### Using the Example Host + +To test your component, use the [`example-host`][example-host] provided in this +repository: + +```console +$ git clone https://github.com/bytecodealliance/component-docs.git +$ cd component-docs/component-model/examples/example-host +$ cp /path/to/adder.component.wasm . +$ cargo run --release -- 5 3 adder.component.wasm +``` + +Expected output: + +``` +5 + 3 = 8 +``` + +[example-host]: https://github.com/bytecodealliance/component-docs/blob/main/component-model/examples/example-host/README.md + +### Using Wasmtime + +You can also test the component directly with `wasmtime`: + +```console +$ wasmtime run --invoke 'add(10, 20)' adder.component.wasm +30 +``` + +## 9. Configurations + +### --derive-eq --derive-show + +These two options will add `derive(Eq)` and / or `derive(Show)` for all the +generated types. + +### --derive-error + +This option will generate variants / enums whose names containing 'Error' as +[suberrors](https://docs.moonbitlang.com/en/latest/language/error-handling.html#error-types). +This allows you to integrate the MoonBit's error handling easier. + +For example, for the following interface: + +```wit +package docs:adder@0.1.0; + +interface add { + record error { + message : string + } + add: func(x: u32, y: u32) -> result; +} + +world adder { + import add; +} +``` + +Will generate the following type: + +```moonbit +pub(all) suberror ComputationError { + Overflow +} derive(Show, Eq) +``` + +and the following function: + +```moonbit +pub fn add(x : UInt, y : UInt) -> Result[UInt, ComputationError] +``` + +which you may use it as: + +```moonbit +fn init { + let a = add(1, 2).unwrap_or_error() catch { Overflow => ... } + +} +``` + +### --ignore-stub + +It happens when you would like to regenerate the project due to the updated +interface, but you don't want the `stub` file to be touched. You may use +`--ignore-stub` option to avoid such modifications. + +### --project-name + +By default, the project name is generated per the name defined in the MoonBit +file. You may use this option to specify the name of the project. It can also be +used if you are generating the project as part of a larger project. + +### --gen-dir + +By default, the exportation parts are generated under `gen`. You may use this +option to specify another directory. + +## 10. References and Further Reading + +- [MoonBit Official Website](https://www.moonbitlang.com/) +- [MoonBit Language Documentation](https://docs.moonbitlang.com/) +- [WebAssembly Component Model](https://component-model.bytecodealliance.org/) +- [WIT Format Specification](https://component-model.bytecodealliance.org/design/wit.html) +- [`wit-bindgen` Documentation](https://github.com/bytecodealliance/wit-bindgen) +- [WebAssembly Tools](https://github.com/bytecodealliance/wasm-tools) +- [Wasmtime Runtime](https://wasmtime.dev/) +- [Component Model Examples](https://github.com/bytecodealliance/component-docs/tree/main/component-model/examples) From 1a241f9092558f9a994f2a31fb56148873006a53 Mon Sep 17 00:00:00 2001 From: zihang Date: Fri, 29 Aug 2025 17:30:28 +0800 Subject: [PATCH 2/6] fix(moonbit): bump tool version and extract code --- .../moonbit/adder-with-error/stub.mbt | 7 ++ .../tutorial/moonbit/adder-with-error/top.mbt | 25 +++++ .../moonbit/adder-with-error/world.wit | 12 ++ .../tutorial/moonbit/adder/moon.pkg.json | 25 +++++ .../examples/tutorial/moonbit/adder/stub.mbt | 6 + .../src/language-support/moonbit.md | 106 ++++-------------- 6 files changed, 94 insertions(+), 87 deletions(-) create mode 100644 component-model/examples/tutorial/moonbit/adder-with-error/stub.mbt create mode 100644 component-model/examples/tutorial/moonbit/adder-with-error/top.mbt create mode 100644 component-model/examples/tutorial/moonbit/adder-with-error/world.wit create mode 100644 component-model/examples/tutorial/moonbit/adder/moon.pkg.json create mode 100644 component-model/examples/tutorial/moonbit/adder/stub.mbt diff --git a/component-model/examples/tutorial/moonbit/adder-with-error/stub.mbt b/component-model/examples/tutorial/moonbit/adder-with-error/stub.mbt new file mode 100644 index 00000000..00ebf417 --- /dev/null +++ b/component-model/examples/tutorial/moonbit/adder-with-error/stub.mbt @@ -0,0 +1,7 @@ +// Generated by `wit-bindgen` 0.45.0. + +///| +fn init { + let _ = @add.add(1, 2).unwrap_or_error() catch { Overflow => ... } + +} diff --git a/component-model/examples/tutorial/moonbit/adder-with-error/top.mbt b/component-model/examples/tutorial/moonbit/adder-with-error/top.mbt new file mode 100644 index 00000000..f5268bcf --- /dev/null +++ b/component-model/examples/tutorial/moonbit/adder-with-error/top.mbt @@ -0,0 +1,25 @@ +// Generated by `wit-bindgen` 0.45.0. DO NOT EDIT! + +///| +pub(all) suberror ComputationError { + Overflow +} derive(Show, Eq) + +///| +pub fn add(x : UInt, y : UInt) -> Result[UInt, ComputationError] { + let return_area = @ffi.malloc(8) + wasmImportAdd(x.reinterpret_as_int(), y.reinterpret_as_int(), return_area) + let lifted4 = match @ffi.load8_u(return_area + 0) { + 0 => Result::Ok(@ffi.load32(return_area + 4).reinterpret_as_uint()) + 1 => { + let lifted = match @ffi.load8_u(return_area + 4) { + 0 => ComputationError::Overflow + _ => panic() + } + Result::Err(lifted) + } + _ => panic() + } + @ffi.free(return_area) + return lifted4 +} diff --git a/component-model/examples/tutorial/moonbit/adder-with-error/world.wit b/component-model/examples/tutorial/moonbit/adder-with-error/world.wit new file mode 100644 index 00000000..b41acc96 --- /dev/null +++ b/component-model/examples/tutorial/moonbit/adder-with-error/world.wit @@ -0,0 +1,12 @@ +package docs:adder@0.1.0; + +interface add { + variant computation-error { + overflow + } + add: func(x: u32, y: u32) -> result; +} + +world adder { + import add; +} diff --git a/component-model/examples/tutorial/moonbit/adder/moon.pkg.json b/component-model/examples/tutorial/moonbit/adder/moon.pkg.json new file mode 100644 index 00000000..f811c802 --- /dev/null +++ b/component-model/examples/tutorial/moonbit/adder/moon.pkg.json @@ -0,0 +1,25 @@ +{ + // link configuration for Wasm backend + "link": { + "wasm": { + "exports": [ + // Export for cabi_realloc + "cabi_realloc:cabi_realloc", + // Export per the interface definition + "wasmExportAdd:docs:adder/add@0.1.0#add" + ], + "export-memory-name": "memory", + "heap-start-address": 16 + } + }, + "import": [ + { + "path": "docs/adder/ffi", + "alias": "ffi" + }, + { + "path": "docs/adder/gen/interface/docs/adder/add", + "alias": "add" + } + ] +} \ No newline at end of file diff --git a/component-model/examples/tutorial/moonbit/adder/stub.mbt b/component-model/examples/tutorial/moonbit/adder/stub.mbt new file mode 100644 index 00000000..c57a3e24 --- /dev/null +++ b/component-model/examples/tutorial/moonbit/adder/stub.mbt @@ -0,0 +1,6 @@ +// Generated by `wit-bindgen` 0.45.0. + +///| +pub fn add(x : UInt, y : UInt) -> UInt { + x + y +} diff --git a/component-model/src/language-support/moonbit.md b/component-model/src/language-support/moonbit.md index 1bd5b878..382eebf4 100644 --- a/component-model/src/language-support/moonbit.md +++ b/component-model/src/language-support/moonbit.md @@ -24,10 +24,11 @@ Verify your MoonBit installation (below are the versions at the time of writing): ``` -$ moon version -moon 0.1.20250801 (edae1ae 2025-08-01) ~/.moon/bin/moon -moonc v0.6.24+012953835 ~/.moon/bin/moonc -moonrun 0.1.20250801 (edae1ae 2025-08-01) ~/.moon/bin/moonrun +$ moon version --all +moon 0.1.20250826 (8ab6c9e 2025-08-26) ~/.moon/bin/moon +moonc v0.6.25+d6913262c (2025-08-27) ~/.moon/bin/moonc +moonrun 0.1.20250826 (8ab6c9e 2025-08-26) ~/.moon/bin/moonrun +moon-pilot 0.0.1-95f12db ~/.moon/bin/moon-pilot ``` ### Installing `wit-bindgen` @@ -51,9 +52,9 @@ Verify the installations (below are the versions at the time of writing): ``` $ wit-bindgen --version -wit-bindgen-cli 0.44.0 (bdb4df54b 2025-08-14) +wit-bindgen-cli 0.45.0 $ wasm-tools --version -wasm-tools 1.237.0 +wasm-tools 1.238.0 ``` ## 2. Define the Interface (WIT) @@ -70,15 +71,7 @@ $ mkdir wit Create `wit/world.wit` with the following content: ```wit -package docs:adder@0.1.0; - -interface add { - add: func(x: u32, y: u32) -> u32; -} - -world adder { - export add; -} +{{#include ../../examples/tutorial/wit/adder/world.wit}} ``` This WIT definition: @@ -146,31 +139,16 @@ The generated files include: ## 4. Examine the Generated Code The `wit-bindgen` tool generates MoonBit bindings that handle the WebAssembly -component interface. Let's examine the generated -`gen/interface/docs/adder/add/stub.mbt`: - -```moonbit -// Generated by `wit-bindgen` 0.44.0. - -pub fn add(_x : UInt, _y : UInt) -> UInt { - ... -} -``` - -The `...` is the placeholder syntax in MoonBit. When executing -`moon check --target wasm`, 'unfinished code' warnings will appear. +component interface. If you execute `moon check`, there will be a warning +suggesting that file `gen/interface/docs/adder/add/stub.mbt` contains unfinished +code, which is what we need to fulfill. ## 5. Implement the Component Logic -Now implement the `add` function in `src/lib.mbt`: +Now implement the `add` function in `gen/interface/docs/adder/add/stub.mbt`: ```moonbit -// Generated by `wit-bindgen` 0.44.0. - -///| -pub fn add(x : UInt, y : UInt) -> UInt { - x + y -} +{{#include ../../examples/tutorial/moonbit/adder/stub.mbt}} ``` ## 6. Configure the Build @@ -178,31 +156,7 @@ pub fn add(x : UInt, y : UInt) -> UInt { Ensure your `gen/moon.pkg.json` is properly configured for WebAssembly target: ```json -{ - // link configuration for Wasm backend - "link": { - "wasm": { - "exports": [ - // Export for cabi_realloc - "cabi_realloc:cabi_realloc", - // Export per the interface definition - "wasmExportAdd:docs:adder/add@0.1.0#add" - ], - "export-memory-name": "memory", - "heap-start-address": 16 - } - }, - "import": [ - { - "path": "docs/adder/ffi", - "alias": "ffi" - }, - { - "path": "docs/adder/gen/interface/docs/adder/add", - "alias": "add" - } - ] -} +{{#include ../../examples/tutorial/moonbit/adder/moon.pkg.json}} ``` ## 7. Build the WebAssembly Component @@ -210,7 +164,7 @@ Ensure your `gen/moon.pkg.json` is properly configured for WebAssembly target: Build the MoonBit code to WebAssembly: ```console -$ moon build --target wasm +$ moon build ``` This generates a WebAssembly module. To create a proper WebAssembly component, @@ -291,41 +245,19 @@ This allows you to integrate the MoonBit's error handling easier. For example, for the following interface: ```wit -package docs:adder@0.1.0; - -interface add { - record error { - message : string - } - add: func(x: u32, y: u32) -> result; -} - -world adder { - import add; -} +{{#include ../../examples/tutorial/moonbit/adder-with-error/world.wit}} ``` -Will generate the following type: +Will generate the following type and function ```moonbit -pub(all) suberror ComputationError { - Overflow -} derive(Show, Eq) -``` - -and the following function: - -```moonbit -pub fn add(x : UInt, y : UInt) -> Result[UInt, ComputationError] +{{#include ../../examples/tutorial/moonbit/adder-with-error/top.mbt}} ``` which you may use it as: ```moonbit -fn init { - let a = add(1, 2).unwrap_or_error() catch { Overflow => ... } - -} +{{#include ../../examples/tutorial/moonbit/adder-with-error/stub.mbt}} ``` ### --ignore-stub From 7e8e658adff24c7f1747bd45af5f97e1ec858fef Mon Sep 17 00:00:00 2001 From: zihang Date: Fri, 29 Aug 2025 17:31:09 +0800 Subject: [PATCH 3/6] chore(moonbit): use rust codefence for highlighting --- component-model/src/language-support/moonbit.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/component-model/src/language-support/moonbit.md b/component-model/src/language-support/moonbit.md index 382eebf4..bd9c421b 100644 --- a/component-model/src/language-support/moonbit.md +++ b/component-model/src/language-support/moonbit.md @@ -147,7 +147,7 @@ code, which is what we need to fulfill. Now implement the `add` function in `gen/interface/docs/adder/add/stub.mbt`: -```moonbit +```rust {{#include ../../examples/tutorial/moonbit/adder/stub.mbt}} ``` @@ -250,13 +250,13 @@ For example, for the following interface: Will generate the following type and function -```moonbit +```rust {{#include ../../examples/tutorial/moonbit/adder-with-error/top.mbt}} ``` which you may use it as: -```moonbit +```rust {{#include ../../examples/tutorial/moonbit/adder-with-error/stub.mbt}} ``` From 6f845612cc03cbc22f4509cec8274f54a3eb1d9d Mon Sep 17 00:00:00 2001 From: zihang Date: Fri, 29 Aug 2025 18:37:49 +0800 Subject: [PATCH 4/6] fix(moonbit): apply suggestions --- .../src/language-support/moonbit.md | 77 ++++++++++--------- 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/component-model/src/language-support/moonbit.md b/component-model/src/language-support/moonbit.md index bd9c421b..81829b22 100644 --- a/component-model/src/language-support/moonbit.md +++ b/component-model/src/language-support/moonbit.md @@ -1,7 +1,8 @@ -# MoonBit Tooling +# MoonBit -MoonBit is a programming language that provides first-class support for -WebAssembly . This guide demonstrates how to build WebAssembly components using +[MoonBit](https://www.moonbitlang.com/) is a programming language that provides first-class support for modern WebAssembly, including WebAssembly components. + +This guide demonstrates how to build WebAssembly components using MoonBit, leveraging WIT (WebAssembly Interface Types) for interface definitions and the `wit-bindgen` toolchain for code generation. @@ -23,7 +24,7 @@ instructions from the Verify your MoonBit installation (below are the versions at the time of writing): -``` +```console $ moon version --all moon 0.1.20250826 (8ab6c9e 2025-08-26) ~/.moon/bin/moon moonc v0.6.25+d6913262c (2025-08-27) ~/.moon/bin/moonc @@ -35,22 +36,21 @@ moon-pilot 0.0.1-95f12db ~/.moon/bin/moon-pilot Install the `wit-bindgen` CLI tool, which generates MoonBit bindings from WIT files: - -``` -$ cargo install wit-bindgen-cli +```sh +cargo install wit-bindgen-cli ``` ### Installing `wasm-tools` Install `wasm-tools` for working with WebAssembly components: -``` -$ cargo install wasm-tools +```sh +cargo install wasm-tools ``` Verify the installations (below are the versions at the time of writing): -``` +```console $ wit-bindgen --version wit-bindgen-cli 0.45.0 $ wasm-tools --version @@ -60,12 +60,14 @@ wasm-tools 1.238.0 ## 2. Define the Interface (WIT) Before generating the MoonBit project, you need to define the component -interface using WIT. Create a directory for your project and define the WIT +interface using WIT. + +Create a directory for your project and define the WIT file: -```console -$ mkdir moonbit-adder && cd moonbit-adder -$ mkdir wit +```sh +mkdir moonbit-adder && cd moonbit-adder +mkdir wit ``` Create `wit/world.wit` with the following content: @@ -85,8 +87,8 @@ This WIT definition: Use `wit-bindgen` to generate the MoonBit project structure and bindings: -```console -$ wit-bindgen moonbit wit/world.wit --out-dir . \ +```sh +wit-bindgen moonbit wit/world.wit --out-dir . \ --derive-eq \ --derive-show \ --derive-error @@ -136,16 +138,16 @@ The generated files include: - `interface/`: Generated import interface bindings - `world/`: Generated import world bindings -## 4. Examine the Generated Code - The `wit-bindgen` tool generates MoonBit bindings that handle the WebAssembly -component interface. If you execute `moon check`, there will be a warning +component interface. + +If you execute `moon check`, there will be a warning suggesting that file `gen/interface/docs/adder/add/stub.mbt` contains unfinished -code, which is what we need to fulfill. +code, which is what we need to complete. ## 5. Implement the Component Logic -Now implement the `add` function in `gen/interface/docs/adder/add/stub.mbt`: +Implement the `add` function in `gen/interface/docs/adder/add/stub.mbt`: ```rust {{#include ../../examples/tutorial/moonbit/adder/stub.mbt}} @@ -161,29 +163,28 @@ Ensure your `gen/moon.pkg.json` is properly configured for WebAssembly target: ## 7. Build the WebAssembly Component -Build the MoonBit code to WebAssembly: +Build the MoonBit code to WebAssembly core module: -```console -$ moon build +```sh +moon build ``` -This generates a WebAssembly module. To create a proper WebAssembly component, -use `wasm-tools`: +To create a proper WebAssembly component from the module we have produced, use `wasm-tools`: -```console -$ wasm-tools component embed wit target/wasm/release/build/gen/gen.wasm \ +```sh +wasm-tools component embed wit target/wasm/release/build/gen/gen.wasm \ --encoding utf16 \ --output adder.wasm -$ wasm-tools component new adder.wasm --output adder.component.wasm +wasm-tools component new adder.wasm --output adder.component.wasm ``` You can verify the component's interface using `wasm-tools`: -```console -$ wasm-tools component wit adder.component.wasm +```sh +wasm-tools component wit adder.component.wasm ``` -Expected output for both commands: +The WIT printed should be similar if not exactly the same as the following: ```wit package root:component; @@ -205,11 +206,11 @@ package docs:adder@0.1.0 { To test your component, use the [`example-host`][example-host] provided in this repository: -```console -$ git clone https://github.com/bytecodealliance/component-docs.git -$ cd component-docs/component-model/examples/example-host -$ cp /path/to/adder.component.wasm . -$ cargo run --release -- 5 3 adder.component.wasm +```sh +git clone https://github.com/bytecodealliance/component-docs.git +cd component-docs/component-model/examples/example-host +cp /path/to/adder.component.wasm . +cargo run --release -- 5 3 adder.component.wasm ``` Expected output: @@ -229,7 +230,7 @@ $ wasmtime run --invoke 'add(10, 20)' adder.component.wasm 30 ``` -## 9. Configurations +## Advanced ### --derive-eq --derive-show From 7616e6a0b3132b9ea647c3ec545973d1888e9115 Mon Sep 17 00:00:00 2001 From: zihang Date: Fri, 5 Sep 2025 17:42:20 +0800 Subject: [PATCH 5/6] fix(moonbit): update installation section --- .../src/language-support/moonbit.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/component-model/src/language-support/moonbit.md b/component-model/src/language-support/moonbit.md index 81829b22..c161bb02 100644 --- a/component-model/src/language-support/moonbit.md +++ b/component-model/src/language-support/moonbit.md @@ -32,20 +32,21 @@ moonrun 0.1.20250826 (8ab6c9e 2025-08-26) ~/.moon/bin/moonrun moon-pilot 0.0.1-95f12db ~/.moon/bin/moon-pilot ``` -### Installing `wit-bindgen` +### Installing Wasm toolchains -Install the `wit-bindgen` CLI tool, which generates MoonBit bindings from WIT -files: -```sh -cargo install wit-bindgen-cli -``` +You need to have the following tools: -### Installing `wasm-tools` +- [wit-bindgen](https://github.com/bytecodealliance/wit-bindgen) for generating MoonBit bindings from WIT +- [wasm-tools](https://github.com/bytecodealliance/wasm-tools) for component conversion +- (optional) [wasmtime](https://github.com/bytecodealliance/wasmtime) for Wasm runtime -Install `wasm-tools` for working with WebAssembly components: +You may choose to download the executable from the respective GitHub releases, or you may, +with [Rust toolchain](https://www.rust-lang.org/tools/install) installed: ```sh +cargo install wit-bindgen-cli cargo install wasm-tools +cargo install wasmtime-cli ``` Verify the installations (below are the versions at the time of writing): @@ -55,6 +56,8 @@ $ wit-bindgen --version wit-bindgen-cli 0.45.0 $ wasm-tools --version wasm-tools 1.238.0 +$ wasmtime --version +wasmtime 36.0.2 ``` ## 2. Define the Interface (WIT) From a1fac790252e69af90bd41c2cc6c29e570de4ec7 Mon Sep 17 00:00:00 2001 From: Victor Adossi <123968127+vados-cosmonic@users.noreply.github.com> Date: Fri, 5 Sep 2025 21:08:21 +0900 Subject: [PATCH 6/6] fix(lang/moonbit): fix numbering of steps --- component-model/src/language-support/moonbit.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/component-model/src/language-support/moonbit.md b/component-model/src/language-support/moonbit.md index c161bb02..80481558 100644 --- a/component-model/src/language-support/moonbit.md +++ b/component-model/src/language-support/moonbit.md @@ -148,7 +148,7 @@ If you execute `moon check`, there will be a warning suggesting that file `gen/interface/docs/adder/add/stub.mbt` contains unfinished code, which is what we need to complete. -## 5. Implement the Component Logic +## 4. Implement the Component Logic Implement the `add` function in `gen/interface/docs/adder/add/stub.mbt`: @@ -156,7 +156,7 @@ Implement the `add` function in `gen/interface/docs/adder/add/stub.mbt`: {{#include ../../examples/tutorial/moonbit/adder/stub.mbt}} ``` -## 6. Configure the Build +## 5. Configure the Build Ensure your `gen/moon.pkg.json` is properly configured for WebAssembly target: @@ -164,7 +164,7 @@ Ensure your `gen/moon.pkg.json` is properly configured for WebAssembly target: {{#include ../../examples/tutorial/moonbit/adder/moon.pkg.json}} ``` -## 7. Build the WebAssembly Component +## 5. Build the WebAssembly Component Build the MoonBit code to WebAssembly core module: @@ -202,7 +202,7 @@ package docs:adder@0.1.0 { } ``` -## 8. Testing the Component +## 6. Testing the Component ### Using the Example Host @@ -281,7 +281,7 @@ used if you are generating the project as part of a larger project. By default, the exportation parts are generated under `gen`. You may use this option to specify another directory. -## 10. References and Further Reading +## References and Further Reading - [MoonBit Official Website](https://www.moonbitlang.com/) - [MoonBit Language Documentation](https://docs.moonbitlang.com/)