State-of-the-art WebAssembly Component Model implementation with Bazel
This example demonstrates WebAssembly component composition using wac_compose, the official WebAssembly Composition (WAC) standard from the Bytecode Alliance.
# Build the checksum updater component
bazel build //examples/multi_language_composition:checksum_updater_simple
# Run the component
wasmtime run bazel-bin/examples/multi_language_composition/checksum_updater_simple.wasm test --verboseFor actual multi-language component composition, see these production examples:
See //examples/multi_profile:* for components with different build profiles:
wac_compose(
name = "development_system",
components = {
":camera_sensor_debug": "sensor:interfaces",
":object_detection_release": "ai:interfaces", # Mix profiles!
},
component_profiles = {
"ai:interfaces": "release", # Override per-component
},
composition = """
let camera = new sensor:interfaces { ... };
let ai = new ai:interfaces { ... };
export ai as main;
""",
)See //test/integration:multi_service_system for component interconnection:
wac_compose(
name = "multi_service_system",
components = {
":service_a_component": "test:service-a",
":service_b_component": "test:service-b",
},
composition = """
let service-a = new test:service-a { ... };
let service-b = new test:service-b {
storage: service-a.storage, // Connect components!
...
};
export service-b as main;
""",
)See //examples/wac_oci_composition:* for production deployment:
wac_remote_compose(
name = "production_system",
components = {
"frontend": "ghcr.io/org/frontend:v1.0",
"backend": "ghcr.io/org/backend:v1.0",
},
composition_file = "production.wac",
)wac_compose uses the official WAC tool from the Bytecode Alliance, ensuring:
- Standards compliance with WebAssembly Component Model
- Proper component interconnection through WIT interfaces
- Full composition language support
- Active development and ecosystem support
- Multi-profile builds - Mix debug/release components
- Per-component configuration - Granular control
- No Python scripts - Windows compatible
- Hermetic builds - Reproducible across platforms
- Component interconnection - Real inter-component communication
| Example | Description | Location |
|---|---|---|
| Multi-Profile | Different build profiles per component | //examples/multi_profile:* |
| Service Integration | Component interconnection patterns | //test/integration:multi_service_system |
| WAC OCI | Production deployment with registries | //examples/wac_oci_composition:* |
| WAC Remote | Remote component composition | //examples/wac_remote_compose:* |
load("@rules_wasm_component//wac:defs.bzl", "wac_compose")
wac_compose(
name = "my_system",
components = {
":frontend_component": "app:frontend",
":backend_component": "app:backend",
},
composition = """
let frontend = new app:frontend { ... };
let backend = new app:backend { ... };
connect frontend.request -> backend.handler;
export frontend as main;
""",
)If you don't specify a composition, wac_compose auto-generates one:
wac_compose(
name = "simple_system",
components = {
":component_a": "pkg:component-a",
":component_b": "pkg:component-b",
},
# No composition specified - auto-generated
)Generates:
let component-a = new pkg:component-a { ... };
let component-b = new pkg:component-b { ... };
export component-a as main;
Components communicate through WebAssembly Interface Types (WIT):
// wit/frontend.wit
package app:frontend@1.0.0;
interface display {
show-message: func(message: string);
}
interface client {
make-request: func(data: string) -> string;
}
world frontend {
export display;
import client;
}use app_frontend_bindings::{
exports::app::frontend::display::Guest,
app::frontend::client,
};
struct Frontend;
impl Guest for Frontend {
fn show_message(message: String) {
println!("Frontend: {}", message);
}
}
app_frontend_bindings::export!(Frontend with_types_in app_frontend_bindings);# Define WIT interfaces
wit_library(
name = "interfaces",
srcs = ["wit/interfaces.wit"],
package_name = "app:interfaces@1.0.0",
world = "app",
)
# Build Rust component
rust_wasm_component_bindgen(
name = "app_component",
srcs = ["src/lib.rs"],
wit = ":interfaces",
profiles = ["debug", "release"],
)
# Compose with other components
wac_compose(
name = "full_system",
components = {
":app_component": "app:interfaces",
":other_component": "other:interfaces",
},
)# Run build tests
bazel test //examples/multi_language_composition:multi_language_tests
# Build all targets
bazel build //examples/multi_language_composition:all
# Run specific composition
wasmtime run bazel-bin/examples/multi_profile/development_system.wasmNote: These characteristics are based on the WebAssembly Component Model architecture. Actual performance depends on runtime implementation (Wasmtime, etc.) and component design.
WAC compositions provide:
- Near-native speed - Direct function calls between components
- Zero-copy sharing - Efficient memory management where possible
- Lazy loading - Components loaded on demand
- Memory isolation - Security through sandboxing
If you're using older composition patterns:
# ❌ OLD: multi_language_wasm_component (removed)
multi_language_wasm_component(
name = "old_composition",
components = [":component"],
composition_type = "simple",
)
# ✅ NEW: wac_compose (official standard)
wac_compose(
name = "new_composition",
components = {
":component": "pkg:component", # label -> WIT package name
},
)
# Or for single component, just use directly:
alias(
name = "new_composition",
actual = ":component",
)This example demonstrates state-of-the-art WebAssembly Component Model implementation with Bazel using the official WAC composition standard from the Bytecode Alliance.