A Bytecode Alliance project
A tool for composing WebAssembly components together.
wac
is a tool for composing WebAssembly Components
together.
The tool uses the WAC (pronounced "whack") language to define how components composed together.
The wac
language is a declarative superset of wit
for describing how components are composed together.
As an example, imagine two components name.wasm and greeter.wasm.
The wit for name.wasm is:
package example:name;
world name {
/// Exporting a 'name' function that returns a name to greet.
export name: func() -> string;
}
And the wit for greeter.wasm is:
package example:greeter;
world greeter {
/// Importing a 'name' function that returns the name to greet.
import name: func() -> string;
/// Exporting a 'greet' function that returns a greeting using the name.
export greet: func() -> string;
}
The following is an example of a wac file that composes these two components together by plugging name.wasm's "name" export into greeter.wasm's "name" import.
package example:composition;
// Instantiate the `name` component
let n = new example:name {};
// Instantiate the `greeter` component by plugging its `name`
// import with the `name` export of the `name` component.
let greeter = new example:greeter {
name: n.name,
};
// Export the greet function from the greeter component
export greeter.greet;
The result of encoding this composition is a single component that does not import anything and only exports the "greet" function.
For a full description of the wac
language see the language guide.
To install the wac
CLI from source, run the following command:
cargo install wac-cli
If you have the cargo-binstall
utility installed, wac
CLI can also be installed via a prebuilt
release artifact, saving time on the installation:
cargo binstall wac-cli
The wac
CLI tool has the following commands:
wac plug
- Plugs the imports of a component with one or more other components.wac compose
- Compose WebAssembly components using the provided WAC source file.wac targets
- Determines whether a given component conforms to the supplied wit world.wac parse
- Parses a composition into a JSON representation of the AST.wac resolve
- Resolves a composition into a JSON representation.
To do simple compositions, use the wac plug
command:
wac plug my-socket.wasm --plug my-plug.wasm -o plugged.wasm
Or mixing in packages published to a Warg registry:
wac plug my-namespace:package-name --plug some-namespace:other-package-name -o plugged.wasm
To see whether a given component implements a given world, use the wac targets
command:
wac targets my-component.wasm my-wit.wit
If my-component.wasm
implements the world defined in my-wit.wit
then the command will succeed. Otherwise, an error will be returned.
If my-wit.wit
has multiple world definitions, you can disambiguate using the --world
flag.
To perform a composition, use the wac compose
command:
wac compose -t input.wac
This will use input.wac
to perform the composition and write the text
representation of the component to stdout.
wac compose -o output.wasm input.wac
This will perform the composition specified in input.wac
and output a WebAssembly component named output.wasm
.
By default, wac
will create a component that embeds its dependencies (i.e. packages
referenced in a WAC source file) inside of itself rather than importing those dependencies;
to cause dependencies to be imported in the output component, use the
--import-dependencies
flag:
wac compose --import-dependencies -o output.wasm input.wac
Dependencies may be located within a deps
subdirectory, with an expected structure of:
deps/
├─ <namespace>/
│ ├─ <package>.wasm
The dependency may be also be a WIT file or a directory containing a WIT package:
deps/
├─ <namespace>/
│ ├─ <package>/
│ │ ├─ a.wit
│ │ ├─ ...
The --deps-dir
CLI option may be used to specify a different directory to
search for dependencies.
The location of specific dependencies may also be specified with the --dep
CLI option:
wac compose --dep foo:bar=./baz.wasm -o output.wasm input.wac
By default, dependencies must be binary-encoded WebAssembly components; to
enable support for WAT files, use the wat
build-time feature.
If built with default features, then dependencies may be
automatically resolved from a Warg registry and do not need to exist in the
deps
subdirectory or specified via the --dep
CLI option.