|
1 |
| -# Distributing Components |
| 1 | +# Distributing and Fetching Components and WIT |
2 | 2 |
|
3 | 3 | Modern applications rely extensively on third-party packages - so extensively that distributing packages is almost an industry in itself. Traditionally, these have been specific to a language. For example, JavaScript developers are used to using packages from NPM, and Rust developers use `crates.io`. Some runtimes support binary distribution and linking, enabling limited cross-language interop; for example, Maven packages can be written in any language that targets the Java runtime. Services like this are variously referred to as "package managers" or "registries."
|
4 | 4 |
|
5 |
| -Publishing and distribution are not defined by the core component model, but will form an important part of the component ecosystem. For example, if you're writing JavaScript, and want to pull in a highly optimised machine learning algorithm written in C and compiled to Wasm, you should be able to invoke it from a registry, just as easily as you would add a NPM package from the NPM registry. |
| 5 | +Publishing and distribution are not defined by the core component model, but form important part of the component ecosystem. For example, if you're writing JavaScript, and want to pull in a highly optimised machine learning algorithm written in C and compiled to Wasm, you can pull it from a registry, ideally just as easily as you would add a NPM package from the NPM registry. |
6 | 6 |
|
7 |
| -Publishing and distribution is a work in progress. The proposed registry protocol is [warg](https://warg.io/), but this is still in development, and there are no public warg registries as yet. You can find more information about the development of the registry protocol [here](https://github.com/bytecodealliance/governance/blob/main/SIGs/SIG-Registries/proposal.md). |
| 7 | +You can get involved with improving the packaging and hosting of Wasm components by joining the [Bytecode Alliance Packaging Special Interest Group (SIG)](https://github.com/bytecodealliance/governance/blob/main/SIGs/sig-packaging/proposal.md). |
| 8 | + |
| 9 | +## Registry Tooling |
| 10 | + |
| 11 | +The [`wasm-pkg-tools` project](https://github.com/bytecodealliance/wasm-pkg-tools) enables fetching and publishing Wasm Components to OCI or Warg registries. It contains a `wkg` CLI tool that eases distributing and fetching components and WIT packages. The following examples walk through using `wkg`. |
| 12 | + |
| 13 | +## Distributing Components Using `wkg` |
| 14 | + |
| 15 | +A component is pushed to an OCI registry using `wkg oci push`. The example below pushes to a GHCR: |
| 16 | + |
| 17 | +```sh |
| 18 | +wkg oci push ghcr.io/user/hello:0.1.0 hello.wasm |
| 19 | +``` |
| 20 | + |
| 21 | +## Fetching Components Using `wkg` |
| 22 | + |
| 23 | +A component is pulled from a OCI registry using `wkg oci pull`. The example below pulls a component from GHCR: |
| 24 | + |
| 25 | +```sh |
| 26 | +wkg oci pull ghcr.io/user/hello:0.1.0 -o hello.wasm |
| 27 | +``` |
| 28 | + |
| 29 | +## Configuring `wkg` to Fetch WASI Packages |
| 30 | + |
| 31 | +The `wkg` tool uses a configuration file to store settings with a default location of `$XDG_CONFIG_HOME/wasm-pkg/config.toml`. It must be configured to know which registry to use for which package namespaces. The following is a convenient configuration to ensure you can fetch WASI packages from the [WebAssembly OCI registry](https://github.com/WebAssembly/WASI/pkgs/container/wasi), where the latest interfaces are published upon WASI releases. |
| 32 | + |
| 33 | +```toml |
| 34 | +# $XDG_CONFIG_HOME/wasm-pkg/config.toml |
| 35 | +default_registry = "ghcr.io" |
| 36 | + |
| 37 | +[namespace_registries] |
| 38 | +wasi = { registry = "wasi", metadata = { preferredProtocol = "oci", "oci" = {registry = "ghcr.io", namespacePrefix = "webassembly/" } } } |
| 39 | + |
| 40 | +[package_registry_overrides] |
| 41 | + |
| 42 | +[registry] |
| 43 | +``` |
| 44 | + |
| 45 | +## Distributing WIT Packages using `wkg` |
| 46 | + |
| 47 | +The `wkg` tool uses a [configuration file](https://github.com/bytecodealliance/wasm-pkg-tools?tab=readme-ov-file#configuration) to store settings with a default location of `$XDG_CONFIG_HOME/wasm-pkg/config.toml`. It must be configured to know which registry to use for which package namespaces. The following configuration, instructs `wkg` to use [ttl.sh](https://ttl.sh/) OCI registry for all packages with the `foo` namespace. |
| 48 | + |
| 49 | +```toml |
| 50 | +# $XDG_CONFIG_HOME/wasm-pkg/config.toml |
| 51 | +default_registry = "ghcr.io" |
| 52 | + |
| 53 | +[namespace_registries] |
| 54 | +foo = { registry = "foo-registry", metadata = { preferredProtocol = "oci", "oci" = {registry = "ttl.sh", namespacePrefix = "wasm-components/" } } } |
| 55 | + |
| 56 | +[package_registry_overrides] |
| 57 | + |
| 58 | +[registry] |
| 59 | +``` |
| 60 | + |
| 61 | +Now, `foo` packages can be built and published using `wkg`. |
| 62 | + |
| 63 | +```sh |
| 64 | +mkdir wit |
| 65 | +cat > wit/foo.wit << EOL |
| 66 | + |
| 67 | +
|
| 68 | +interface do-something { |
| 69 | + reduce: func(a: u32, b: u32) -> u32; |
| 70 | +} |
| 71 | +
|
| 72 | +world example { |
| 73 | + export do-something; |
| 74 | +} |
| 75 | +EOL |
| 76 | + |
| 77 | +wkg wit build |
| 78 | + |
| 79 | +``` |
| 80 | + |
| 81 | +This will publish the component to `ttl.sh/wasm-components/foo/bar:0.1.0` |
| 82 | + |
| 83 | +## Configuring `wkg` to Fetch Custom Packages |
| 84 | + |
| 85 | +After configuring `wkg` to know where to pull `foo` namespaced packages from, the `bar` package can be pulled with `wkg get`: |
| 86 | + |
| 87 | +```sh |
| 88 | +wkg get --format wit foo: [email protected] |
| 89 | +``` |
| 90 | + |
| 91 | +## Fetching WIT Package Dependencies using `wkg` |
| 92 | + |
| 93 | +Sometimes fetching a single package is not sufficient because it depends on other packages. For example, the following world describes a simple Wasm service which requires `wasi:http/proxy``: |
| 94 | + |
| 95 | +```wit |
| 96 | +package foo:wasi-http-service; |
| 97 | +
|
| 98 | +world target-world { |
| 99 | + include wasi:http/[email protected]; |
| 100 | +} |
| 101 | +``` |
| 102 | + |
| 103 | +One may be tempted to simply get the `wasi:http` package with `wkg get --format wit wasi:[email protected] -o wit/deps/http/`. However, `wasi:http` depends on other WASI packages such as `wasi:clocks` and `wasi:io`. To make sure to fetch a package and all its dependencies, use `wkg fetch`, which will read the package containing the world(s) you have defined in the given wit directory ( `wit` by default). It will then fetch the |
| 104 | +dependencies and write them to the `deps` directory along with a lock file. |
| 105 | + |
| 106 | +After placing the above file in `./wit`, run the following to fetch the dependencies: |
| 107 | + |
| 108 | +```sh |
| 109 | +wkg wit fetch |
| 110 | +``` |
| 111 | + |
| 112 | +The `./wit` directory will be populated as follows: |
| 113 | +```sh |
| 114 | +wit |
| 115 | +├── deps |
| 116 | +│ ├── wasi-cli-0.2.3 |
| 117 | +│ │ └── package.wit |
| 118 | +│ ├── wasi-clocks-0.2.3 |
| 119 | +│ │ └── package.wit |
| 120 | +│ ├── wasi-http-0.2.3 |
| 121 | +│ │ └── package.wit |
| 122 | +│ ├── wasi-io-0.2.3 |
| 123 | +│ │ └── package.wit |
| 124 | +│ └── wasi-random-0.2.3 |
| 125 | +│ └── package.wit |
| 126 | +└── world.wit |
| 127 | +``` |
| 128 | + |
| 129 | +Now, you can use the language toolchain of your choice to generate bindings and create your component. |
0 commit comments