Skip to content
WASM Analyzer LogoWASM Analyzer LogoWASM Analyzer
GitHub

The Wasm Interface Type text format

The Wasm Interface Type text format (WIT) is an Interface Description Language (IDL)—a language that facilitates communication between programs or objects created in different languages. IDL definitions are agnostic, or language-independent, working as intermediaries between two or more programming languages.

The WIT format is intended to be legible for humans, and to complement the WebAssembly component model. A basic tenet behind WIT is that it should be easy to read and write for developers.

The aim of the creators of WIT is to provide a foundation for producing components from guest programming languages. These components should then be usable by host programming languages.





Keywords


WIT uses the following keywords:

keywordexplanation
exportMakes an item accessible from host language.
funcFunction, read more
importDefines component requirement; Imports must be passed through constructor when components are instantiated.
interfaceCollection of functions and types, read more
packageCollection of one or more .wit files, or units of WIT code, with an identifying ID, read more
staticFunction declaration for functions without implicit self parameters
typeType declaration, read more
unionVariant type, where all variant entries have a type payload
useDefines import in interface.
variantType containing a list of valid types; An item typed as a variant must match one of the listed variant types.
worldCollection of exports and/or imports

WIT supports a greater range of types than Wasm code. For a list of types, have a look at the following section.

You can read more about WIT in the WebAssembly component model repository on Github, here, or continue on to read our summary of the WIT building blocks.





WIT types


WIT supports the following predefined types:

typeexplanation
boolboolean
charcharacter
enumenumerator
flagsbitset structure with named bits
float3232-bit floating point data
float6464-bit floating point data
handleresource reference, can be borrowed or owned*
ididentifier
listcollection of values
optionoption type (encapsulates optional value)
recordrecord type (collection with fixed number of values/named fields)
resultresult type (holds a return value or error value)
s8signed 8-bit integer
s16signed 16-bit integer
s32signed 32-bit integer
s64signed 64-bit integer
stringstring
tupletuple (collection with fixed number of (two) values)
u8unsigned 8-bit integer
u16unsigned 16-bit integer
u32unsigned 32-bit integer
u64unsigned 64-bit integer
unionunion type (compound of several possible types, where all entries have a typed payload)
variantvariant type (compound of several possible types)

* An owned handle will call the destructor for the resource it refers to, when dropped. A borrowed handle will not call the destructor.


WIT also allows for user defined types, examples of which can be seen below.





WIT packages


WIT text, or code, is organized into packages. Each package is represented by a directory, containing WIT code separated into files. WIT packages can contain interfaces and worlds.

Type definitions within a WIT package can be shared between files. Type definitions are most easily shared between files within the same package with a use statement, but types may also be shared between packages, with the addition of an identifying package ID to the use statement.

Valid WIT package files have the file ending .wit, and should be encoded as UTF-8.


Package membership is also defined within a file, in the following format:

package local:example




WIT interface declaration


Now, consider the following type interface, belonging to the previously defined package:

package local:example

interface my-types {
  record a-record {
    small-number: u32,
    big-number: u64,
  }

  record another-record {
    a-number: u32,
    another-number: u32,
  }

  type some-number = u32
}

Import the types above within the same package like this:

package local:example

interface another-interface {
  use my-types.{a-record, another-record, some-number}
}

Import the same types into a file belonging to another package by adding the package ID to the use statement:

package local:another-example

interface another-interface {
  use local:example/my-types.{a-record, another-record, some-number}
}

The examples above include interface definitions. Keep reading for more information about these interfaces.





WIT interfaces


WIT is built around the interface format, and interface definitions sit at the top level of WebAssembly components. interface is a collection of functions and types. WIT interfaces make Wasm code available to external code, and work much as a more traditional instance of a Wasm module.

A WIT interface can be seen as a collection of functions, types and use statements. Like a Wasm module, a WIT interface defines exports and imports.


A WIT interface can be defined as:

interface my-interface {
  // interface contents
}

Key features of WIT interfaces:

  • functions
  • resources
  • types


WIT functions


In WIT, a function can be defined as:

my-function: func(param: string)

When examining this statement, we find that a function declaration starts off with a label, or name:

my-function:

After the label, we have the definition of the function itself. It starts off with the keyword func, for “function”, and then gets to the definition of parameters:

func(param: string)

Note that parameters are typed, and that the typing used can be either pre-defined types, like string in the example above, or user-defined types.



WIT resources

A WIT resource is defined as an entity with a limited lifetime that can only be passed indirectly via handle values. The abstract resource type is used in interfaces for items that shouldn’t be copied by value. In WIT, resource statements can look something like:

resource my-resource

But a resource definition can also have a body, which enables statements like:

resource my-resource {
  constructor(init: u32)          // 0-1 constructors per resource
  some-function: func(param: u32) // a resource definition can contain function definitions
}


WIT worlds


A WIT world can be said to describe the type of a component, and it sits at the top level of a WebAssembly component. Worlds describe components, and define named imports and exports. Worlds can be structured as either component interfaces, or functions.


A WIT world can be defined as:

world my-world {
  import local:example/my-types
  export local:example/my-types
}