Skip to content

andreiltd/wasmono

Repository files navigation

Wasmono

Buck2 rules for building WebAssembly components.

See also similar rules for bazel: https://github.com/pulseengine/rules_wasm_component

Quick Start

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

Features

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

Build a Component

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'],
)

Available Rules

Component Rules

  • wasm_component - Create component from WASM module + WIT
  • wasm_component_link - Link multiple components
  • wasm_plug - Compose components using plug pattern
  • wasm_compose - Compose components using WAC composition files
  • wasm_validate - Validate WASM binaries
  • wasm_print - Convert WASM to text format
  • wasm_opt - Optimize WASM modules with Binaryen
  • wasm_weval - Partially evaluate WASM modules with weval
  • wasm_wizer - Pre-initialize WASM modules with wasmtime wizer

Binding Generation

  • wit_bindgen_rust - Generate Rust bindings
  • wit_bindgen_c - Generate C bindings
  • wit_bindgen_cxx - Generate C++ bindings
  • wit_to_markdown - Generate documentation

JavaScript

  • wasm_componentize_js - Build component from JavaScript (via jco)

Package Management

  • wasm_package - Download packages from registries
  • wit_library - Define a WIT library with automatic dependency resolution (via wkg)

Example: Multi-Component App

# 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"],
)

Toolchains

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:

  1. Distribution: Downloads and extracts the tool binary
  2. 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:

Using as an External Cell

Wasmono can be used as a git external cell in other Buck2 projects.

1. Configure .buckconfig

[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:default

Create an empty none/BUCK file (required by cell aliases).

2. Set up toolchains/BUCK

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"])

3. Add platforms/BUCK

platform(
    name = "wasm32_wasi",
    constraint_values = [
        "config//cpu/constraints:wasm32",
        "config//os/constraints:wasi",
    ],
)

4. Use the rules

load("@wasmono//toolchains/wasm:component.bzl", "wasm_component", "wasm_compose")

Custom Tool Releases

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.

Example: Using a newer wasm-tools version

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

Acknowledgments

The http example is port of great p3 demo from https://github.com/ejrgilbert/component-interposition

About

Buck2 rules for building WebAssembly components

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors