Build
The wash CLI command includes a build subcommand that can be used to build WebAssembly components.
See the wash build CLI reference page for more information on available flags.
The rest of this page will focus on practical examples of using the wash build command.
Language support
Some languages (like Rust and Go) have support built-in to wash, while others require extra customization. A list of languages
with built-in support is published in the wasmcloud.toml specification.
Example projects written in languages with native support can be built by running:
wash build- Rust
 - TinyGo
 - TypeScript
 - Python
 - My Language Isn't Listed
 
While you can always use the standard Rust toolchain and Bytecode Alliance tooling (like wkg for fetching WIT packages) to build your components,
wash build's native support for Rust projects makes building components easier.
The wash build subcommand performs the same tasks as the following commands using tooling from the wider ecosystem:
# Fetch wit dependencies (see https://github.com/bytecodealliance/wasm-pkg-tools)
wkg wit fetch
# Build the WebAssembly component with the native Rust toolchain
cargo build --release --target wasm32-wasip2
# Sign the built WebAssembly component with your generated keys, using information in wasmcloud.toml
wash claims sign ./target/wasm32-wasip2/release/http_hello_world.wasm --destination http_hello_world_s.wasmWith native support for Rust implemented in wash build, the above simplifies to:
wash buildWhile you can always use the standard Go and TinyGo toolchains and Bytecode Alliance tooling (like wkg for fetching WIT packages) to build your components,
wash build's native support for Go projects makes building components easier.
The wash build subcommand performs the same tasks as the following commands using tooling from the wider ecosystem:
# Fetch wit dependencies
wkg wit fetch
# Generate the Go types and bindings
go generate
# Build the Wasm component
tinygo build --target=wasip2 --wit-package ./wit --wit-world componentWith native support for Go implemented in wash build, the above simplifies to:
wash buildIn a TypeScript project, the wash build subcommand must be customized (via the [component] section in wasmcloud.toml) to use external JS-native tooling.
TypeScript builds require an installation of NodeJS and npm. After running npm install,
jco (and ComponentizeJS underneath) can be used to compile the transpiled JavaScript code into a WebAssembly Component.
[component]
build_command = "npm run build"An example build script in your package.json might look like the following:
  "scripts": {
    "build:js": "tsc",
    "build:component": "jco componentize -w wit -o dist/your-component.wasm dist/your-component.js",
    "build": "npm run build:js && npm run build:component",In our quickstart example, the wash build subcommand performs the same tasks as the following commands using tooling from the wider ecosystem:
# Fetch wit dependencies
wkg wit fetch
# You must run `npm install` first
npm install
# Transpile TypeScript code to JavaScript
tsc
# Componentize JavaScript code
jco componentize -w wit -o dist/index.wasm dist/index.js
# Sign the Wasm component with your generated keys, using information in wasmcloud.toml
wash build --sign-only --config-path wasmcloud.tomlIn a Python project, the wash build subcommand must be customized (via the [component] section in wasmcloud.toml) to use external Python-native tooling.
Python builds require an installation of Python, pip and componentize-py
(which can be installed with pip).
With Python ecosystem tooling in place, we can compile Python code into a WebAssembly Component. Modify the [component] section of
wasmcloud.toml to have the following build_command:
[component]
build_command = "componentize-py -d ./wit -w hello componentize app -o build/http_hello_world.wasm"In our quickstart example, the wash build subcommand performs the same tasks as the following commands using tooling from the wider ecosystem:
# Fetch wit dependencies
wkg wit fetch
# Componentize Python code into a WebAssembly Component
componentize-py -d ./wit -w hello componentize app -o build/http_hello_world.wasm
# Sign the Wasm component with your generated keys, using information in wasmcloud.toml
wash build --sign-only --config-path wasmcloud.tomlThe wash build subcommand allows for building arbitrary languages into WebAssembly components via configuring wasmcloud.toml, for languages without built-in support.
For example, following the Javascript ComponentizeJS example documentation, you can set up your wasmcloud.toml file like so:
name = "componentize-js"
language = "rust"
type = "component"
[component]
claims = ["wasmcloud:httpserver"]
build_command = "node componentize.mjs"
build_artifact = "hello.component.wasm"
destination = "hello_s.component.wasm"Overriding the build_command allows you to use an external script or command to build the component, then specifying where the build_artifact is (wherever the component should be after the build command completes) lets wash still
sign the component using your generated keys and other configuration in wasmcloud.toml.
Note that running wash build with a custom build_command configured does not have full support for environment variables or multiple commands
and should be in the form of "command arg1 arg2 arg...". It's recommended to use a single external script to handle more complex build commands.
Interface dependencies and wash build
When you run wash build, wash reads the specified world in your WIT files and downloads the appropriate dependencies automatically into the wit/deps directory. As such, in most cases you should add wit/deps to your .gitignore file and commit the generated wasmcloud.lock file.
Without any additional configuration, wash can download dependencies from the following namespaces (i.e. the wasi in wasi:http@0.2.1):
wasi: Interfaces proposed for the common WebAssembly System Interface (WASI) standardwasmcloud: Interfaces maintained as part of the wasmCloud project (see the Capability Catalog to find first-party interfaces)wrpc: Interfaces maintained as part of the WIT-over-RPC (wRPC) projectba: Interfaces maintained by the Bytecode Alliance
In most cases, dependency fetching and management should be fairly straightforward! As your usage of Wasm grows, however, you are likely to use dependencies that are not in the above namespaces (such as internal registries or other remappings). Also, if you plan to publish any custom interfaces, you will need to configure your registry with credentials. For instructions on registry authentication, see the Publish page.
WIT interfaces are packaged and distributed as OCI artifacts. You can learn more about how the wasmCloud ecosystem uses OCI artifacts on the Packaging page.
Migrating from wit-deps
Older versions of wash required a separate step using a wit-deps tool to download dependencies. This is no longer necessary with the newest versions of wash. To preserve backwards compatibility, if a deps.toml file is found in the wit directory of the project, wash will not fetch dependencies for you. To migrate to the new dependency management system, simply remove the deps.toml file and run wash build again. wash build will automatically remove all the old dependencies and download the new ones into your wit/deps directory.
If you are using some of the provided wrpc interfaces like wrpc:blobstore, you will need to continue using wit-deps. This is due to an issue where some of the wrpc interfaces use syntax that is not yet available in the main WIT parser (but will be when WASI 0.3 is released) which causes the dependency resolution to fail.