Welcome to the new Golem Cloud Docs! 👋
Common Guides
Shared WIT Packages

Shared WIT packages

When having multiple components in an application, we often want to share some of the WIT types between them. The application template used by golem app new contains a predefined way to add these shared packages.

Create a new package

The application's root directory has a wit directory, initially only containing an empty common.wit file. This file is just there to satisfy the requirements of some build tools, such as wit-bindgen. It should not be modified.

Instead, create a new package in a subdirectory of wit/deps, for example wit/deps/shared/shared.wit. Each subdirectory of wit/deps must contain one particular package, but these packages can consist of multiple WIT files.

For example the shared.wit file can define an interface with a few data types:

package myapp:shared;
 
interface types {
    type name = string;
    record user {
        id: u64;
        name: name;
    }
}

Importing the shared package

To import this shared package into one or more of the component's WIT files, just add an import statement to the component's world like in the following example:

package myapp:component1;
 
// ...
 
world component1 {
    import myapp:shared/types;
 
    // ...
}

and use the use statement to import members of the shared interface into another one:

interface api {
    use myapp:shared/types.{name, user};
 
    // ...
}

There is no other steps required - golem app build will automatically find the shared package and wire everything together as expected.

Sharing code between components depending on shared WIT packages

The application templates contain predefined "shared" libraries for most supported languages which can be used to shared code between components.

These are located in the common-* directories, where * is the language. For example, the common-rust directory contains additional Rust crate that can be added as dependencies to the component implementations.

When using shared WIT packages like above, it makes sense to write shared code depending on the bindings generated from these shared WIT packages. For example, there could be a JSON codec implemented for the above defined user record type which we want to use in multiple components.

Doing so requires setting up a custom binding generation step, which depends on the language being used:

First add the wit-bindgen crate as a dependency to your shared crate under the common-rust directory:

[dependencies]
wit-bindgen = "0.37.0"

Then use the binding generator macro pointing to the shared WIT package, for example:

use wit_bindgen::generate;
 
generate!({
    path: "../../wit",
    inline: r#"
    package common:inline;
 
    world common {
        import myapp:shared/types;
    }
    "#,
    // additional_derives: [serde::Deserialize, serde::Serialize],
    generate_all,
    generate_unused_types: true
});
 
use crate::myapp::shared::types::*;