Buck2 rules for building WebAssembly components.
See also similar rules for bazel: https://github.com/pulseengine/rules_wasm_component
Probably the easiest way of getting buck2 is via dotslash (https://dotslash-cli.com). This will also ensure using the buck2 version that the rules were tested against.
cargo binstall dotslash
#Run hello world example
./buck2 run //examples/hello:run
# Run the validator example
./buck2 run //examples/validator/runner:validator -- "Hello World"
# Run the http example
./buck2 run //examples/http/runner:runner- Component Building: Create WASM components from Rust, C, and C++
- WIT Bindings: Generate language bindings from WIT definitions
- Composition: Link, plug, and compose components together (via WAC)
- Package Management: Fetch components from WASM registries
- Optimization: Run wasm-opt (Binaryen) on modules
- Partial Evaluation: Specialize WASM interpreters into compiled code (via weval)
- Pre-initialization: Snapshot module initialization state (via wasmtime wizer)
- JavaScript Components: Build components from JavaScript (via jco)
load("@toolchains//wasm:component.bzl", "wasm_component")
# Build the Rust binary with WASM target
rust_binary(
name = "regex",
crate = "regex",
crate_root = "src/lib.rs",
edition = "2024",
srcs = glob(["src/**/*.rs"]) + glob(["wit/**/*.wit"]),
deps = [
"//third-party:regex",
"//third-party:wit-bindgen",
],
)
# Promote output of regex to wasm component
wasm_component(
name = "regex_component",
module = ":regex",
wit = "wit/regex.wit",
visibility = ['PUBLIC'],
)wasm_component- Create component from WASM module + WITwasm_component_link- Link multiple componentswasm_plug- Compose components using plug patternwasm_compose- Compose components using WAC composition fileswasm_validate- Validate WASM binarieswasm_print- Convert WASM to text formatwasm_opt- Optimize WASM modules with Binaryenwasm_weval- Partially evaluate WASM modules with wevalwasm_wizer- Pre-initialize WASM modules with wasmtime wizer
wit_bindgen_rust- Generate Rust bindingswit_bindgen_c- Generate C bindingswit_bindgen_cxx- Generate C++ bindingswit_to_markdown- Generate documentation
wasm_componentize_js- Build component from JavaScript (via jco)
wasm_package- Download packages from registrieswit_library- Define a WIT library with automatic dependency resolution (via wkg)
# Regex component (Rust)
rust_binary(
name = "regex_lib",
srcs = glob(["src/**/*.rs"]),
)
wasm_component(
name = "regex_component",
module = ":regex_lib",
wit = "wit/regex.wit",
)
# Validator component (C++)
wit_bindgen_cxx(
name = "validator_bindings",
world = "validator",
wit = ["wit/validator.wit"],
)
cxx_binary(
name = "validator",
srcs = ["src/validator.cpp"],
deps = [":validator_bindings"],
)
wasm_component(
name = "validator_component",
module = ":validator",
wit = "wit/validator.wit",
)
# Compose: plug regex into validator
wasm_plug(
name = "app",
socket = ":validator_component",
plugs = [":regex_component"],
)All toolchains are hermetic - they download specific versions of tools rather than relying on system installations. This ensures reproducible builds across different environments.
Each toolchain is composed of two parts:
- Distribution: Downloads and extracts the tool binary
- Toolchain: Provides convenient wrappers and subcommands
This separation makes it easy to control tool sources and versions:
# Download the distribution
download_wasm_tools(
name = "wasm_tools_dist",
version = "1.239.0",
)
# Create toolchain from distribution
wasm_tools_toolchain(
name = "wasm_tools",
distribution = ":wasm_tools_dist",
visibility = ["PUBLIC"],
)Available toolchains:
- wasm-tools - Component manipulation (https://github.com/bytecodealliance/wasm-tools)
- wit-bindgen - Binding generation (https://github.com/bytecodealliance/wit-bindgen)
- wac - Component composition (https://github.com/bytecodealliance/wac)
- wkg - Package management (https://github.com/bytecodealliance/wasm-pkg-tools)
- wasi-sdk - C/C++ wasi toolchain (https://github.com/WebAssembly/wasi-sdk)
- binaryen - WASM optimizer / wasm-opt (https://github.com/WebAssembly/binaryen)
- jco - JavaScript component toolchain (system install, https://github.com/bytecodealliance/jco)
- weval - WASM partial evaluator (opt-in, https://github.com/bytecodealliance/weval)
- wasmtime - WASM runtime, also provides wizer pre-initialization (https://github.com/bytecodealliance/wasmtime)
Wasmono can be used as a git external cell in other Buck2 projects.
[cells]
root = .
wasmono = wasmono
toolchains = toolchains
prelude = prelude
none = none
[cell_aliases]
config = prelude
ovr_config = prelude
fbcode = none
fbsource = none
fbcode_macros = none
buck = none
[external_cells]
prelude = bundled
wasmono = git
[external_cell_wasmono]
git_origin = https://github.com/andreiltd/wasmono.git
commit_hash = <sha1>
[build]
execution_platforms = prelude//platforms:default
[parser]
target_platform_detector_spec = target:root//...->prelude//platforms:defaultCreate an empty none/BUCK file (required by cell aliases).
The wasmono rules reference toolchains//:wasm_tools, toolchains//:wit_bindgen, etc.
You must define these targets in your own toolchains/BUCK. The wasm_demo_toolchains()
macro creates all WASM toolchain targets with sensible defaults:
load("@prelude//toolchains:cxx.bzl", "system_cxx_toolchain")
load("@prelude//toolchains:genrule.bzl", "system_genrule_toolchain")
load("@prelude//toolchains:python.bzl", "system_python_bootstrap_toolchain")
load("@prelude//toolchains:rust.bzl", "system_rust_toolchain")
load("@wasmono//toolchains/wasm:demo.bzl", "wasm_demo_toolchains")
load("@wasmono//toolchains/cxx/wasi:defs.bzl", "download_wasi_sdk", "cxx_wasi_toolchain")
_DEFAULT_TRIPLE = select({
"config//os:wasi": select({
"config//cpu:wasm32": "wasm32-wasip2",
}),
"config//os:linux": select({
"config//cpu:arm64": "aarch64-unknown-linux-gnu",
"config//cpu:x86_64": "x86_64-unknown-linux-gnu",
}),
"config//os:macos": select({
"config//cpu:arm64": "aarch64-apple-darwin",
"config//cpu:x86_64": "x86_64-apple-darwin",
}),
})
system_genrule_toolchain(name = "genrule", visibility = ["PUBLIC"])
system_cxx_toolchain(name = "cxx", visibility = ["PUBLIC"])
system_python_bootstrap_toolchain(name = "python_bootstrap", visibility = ["PUBLIC"])
system_rust_toolchain(
name = "rust",
default_edition = "2024",
rustc_target_triple = _DEFAULT_TRIPLE,
visibility = ["PUBLIC"],
)
# WASM toolchains
wasm_demo_toolchains()
download_wasi_sdk(name = "wasi_sdk", version = "27.0")
cxx_wasi_toolchain(name = "cxx_wasi", distribution = ":wasi_sdk", visibility = ["PUBLIC"])platform(
name = "wasm32_wasi",
constraint_values = [
"config//cpu/constraints:wasm32",
"config//os/constraints:wasi",
],
)load("@wasmono//toolchains/wasm:component.bzl", "wasm_component", "wasm_compose")By default, download_* functions and wasm_demo_toolchains() look up tool
versions from the built-in release dictionaries shipped with wasmono. If you
need a version that isn't included yet — or want to use a dev/nightly build —
you can supply your own release data via the releases parameter.
Custom releases overlay the built-in releases: entries you provide take precedence, while built-in versions remain available as fallback.
Create a single releases file in your repo:
# my_releases.bzl
my_releases = {
"wasm_tools": {
"1.250.0": {
"x86_64-linux": {
"url": "<url>/wasm-tools-1.250.0-x86_64-linux.tar.gz",
"shasum": "<sha256>",
},
"aarch64-macos": {
"url": "<url>/wasm-tools-1.250.0-aarch64-macos.tar.gz",
"shasum": "<sha256>",
},
# ... add platforms you need
},
},
}Then pass it to wasm_demo_toolchains():
load(":my_releases.bzl", "my_releases")
load("@wasmono//toolchains/wasm:demo.bzl", "wasm_demo_toolchains")
wasm_demo_toolchains(
wasm_tools_version = "1.250.0",
releases = my_releases,
)The http example is port of great p3 demo from https://github.com/ejrgilbert/component-interposition