Skip to content

Module manifest

The manifest is the literal object under manifest in module.ts. The build reads it without running code, checks every field, and writes it to the release’s module.json together with the sha256 pins. Unknown fields are errors. See Author a module.

Field Type Meaning
id string Lower-case letters, digits and hyphens, starting with a letter, at most 63 characters.
version string A semantic version. A release is tagged v<version>.
abi "wasi", "component", "emscripten", "bindgen" or "raw" How the WebAssembly expects to be run. oxidevm wasm inspect file.wasm reports what a binary appears to use.
artifacts { name, from }[] Files of the repository that the release carries, at most 64. name is a flat file name; from is a normalized path inside the repository.
process { kind: "command" } or { kind: "service", exclusive?: "workspace" } A command runs once. A service listens until stopped; exclusive: "workspace" makes a second start in the same workspace fail with a busy error, across the page’s VMs and tabs.
commands string[] Command modules only. 1 to 16 unique names, stored sorted, each matching ^[a-z0-9][a-z0-9_.+-]{0,63}$ and none starting with oxidevm. Once an application turns them on for a VM with enableModuleCommands, programs there run each as /usr/local/bin/<name>. See Commands that programs in the VM run.
expose record of endpoints Required for a service, absent for a command. See Endpoints.
requires.host capability[] Host operations the adapter uses, and at most one network reach token. See Host operations.
network { hosts?, purpose? } Only with net.internet. hosts is up to 32 DNS names the module contacts by default, a leading *. allowed, stored sorted; purpose is one sentence of up to 200 characters. Shown at install and by oxidevm wasm doctor, never enforced. See Network.
requires.browser feature[] "cross-origin-isolated", "indexeddb", "jspi" or "web-locks". Checked before the adapter runs. The module frame has no IndexedDB and no Web Locks, so a manifest that names "indexeddb" or "web-locks" cannot start (wasm-module-prerequisite).
requires.guest.executables string[] Absolute paths of Linux programs that must exist in the image. The module’s own commands cannot be listed.
mounts { guest, access, durability? }[] Guest paths the module reads ("ro") or reads and writes ("rw"). Shown on the consent card; nothing enforces them.
state.durable string[] Guest paths that keep the module’s data between starts.
guestFiles { artifact, to, mode? }[] Artifacts written into the guest before the adapter starts. Each is replaced atomically, with mode 0644 unless given, and a start that cannot write one exits with 120.
limits { clients?, startupMs? } clients is how many connections a service serves at once (default 4). A client that connects and stays silent keeps its slot until it closes, because the runner sets no idle timeout; an adapter that needs one closes idle connections itself. startupMs bounds startup (default two minutes).
options record of option declarations What the application may set. See Options.
license { spdx, notices?, source? } An SPDX expression, the artifacts that carry notices, and, for a copyleft license, where the complete source is.
upstream { name, version, source }[] The programs the artifacts were taken from.

requires.host lists capabilities. The adapter’s host has exactly the members of the capabilities listed, plus the base members.

Capability host member Provides
files.sync fs Synchronous file operations on the VM’s files
files.async files The same operations as promises that accept an AbortSignal
files.at at Descriptor-relative, positional and readiness operations, all synchronous: openat with confinement beneath a held directory, statAt, mkdirAt, unlinkAt, renameAt, linkAt, symlinkAt, readlinkAt (bytes), utimensAt (nanoseconds), pread, pwrite, status flags, getdents with resume cookies, fdatasync, and poll with a timeout. Used by kit.wasi.
clock clock The VM’s realtime and monotonic clocks, in nanoseconds
random random The VM’s entropy
sockets.connect sockets Raw client sockets. Needs a reach token: oxidevm wasm build refuses it alone. Listening belongs to the runner and is declared by expose.
net.vm net Network reach: programs in this VM, over loopback, Unix sockets and the VM’s own addresses. Also installs fetch and WebSocket.
net.internet net Network reach: also public hosts on TCP 80 and 443 through the VM’s relay connection, with DNS. Includes net.vm.
process.info process.info, process.cwd This process’s id, credentials and directory
process.spawn process.spawn, process.wait, process.signal Native child processes
process.sync process.infoSync, process.spawnSync, process.waitSync, process.signalSync, process.runSync The same as synchronous calls that block only the module’s worker, for programs that cannot await. runSync runs a child to completion with binary input and output, a deadline and output limits; the child is killed with the module process.
process.signals process.signals Trapping SIGHUP, SIGINT, SIGQUIT, SIGTERM, SIGUSR1, SIGUSR2 and the real-time signals instead of their default action, blocking and unblocking signals, listing pending ones, and raising a signal. See host.process.signals.

net.vm and net.internet need SDK 0.0.10 or later (Userspace API 146), and so do signal masks and real-time signals. files.at, clock, random and process.sync need SDK 0.0.14 or later (Userspace API 147). Name at most one of net.vm and net.internet.

A manifest declares how far the module reaches: no token, net.vm or net.internet. The engine enforces it for each module process. A module.json built by an earlier CLI that names sockets.connect alone has VM-only reach. An internet module may add network to disclose its default hosts and purpose:

requires: { host: ["files.sync", "net.internet"] },
network: { hosts: ["api.example.com"], purpose: "Downloads the current rates." },

module.json stays at schema 1. SDK 0.0.9 and earlier refuse the tokens and the network field, so update the SDK and the CLI together before you install or build such a module. See Module networking.

Each entry of expose has a protocol label and one of two shapes:

Shape Rule
{ kind: "unix", path, protocol } The path is under /workspace/_oxidevm/ or /tmp/.
{ kind: "tcp", port, protocol } Loopback only, on a port from 1024 to 65535.

A service’s adapter must have exactly one handler per key of expose. The runner removes a socket file that nothing listens on (the start fails as busy when another process does), binds each endpoint, and serves at most limits.clients connections at once; extra connections are closed at once.

An application passes options to spawnModule, or to enableModuleCommands, where they apply to every run of the module’s commands. Each declaration is one of:

type Fields Value
boolean default? boolean
integer min, max, default? number
string maxLength, default? string
enum values, default? one of values
enum-set values, default? a subset of values

An option without a default is required. The runner validates the options again at start, and the adapter sees them with defaults applied.

license.spdx must be a valid SPDX expression. A copyleft license such as GPL, LGPL or MPL requires license.source. Each name in license.notices must be a declared artifact. The build warns when it bundles third-party code that license.spdx does not name.