wit-interface-design
WIT Interface Design
Design the contract first, then write the code. A good WIT API reads as a capability grant: someone can look at a component's imports and know exactly what it is allowed to do. The rules below are modeled on the WASI 0.3.x proposals (wasi:cli, clocks, filesystem, http, random, sockets) and wasmcloud:secrets@2.1.0.
Start with the four areas
Every component's contract has four parts. Settle each one before writing WIT.
| Area | Question | Where it lives in WIT |
|---|---|---|
| Triggers | What events, requests or streams start the component's work? | Exports |
| Responses | What does it return, and who owns the data? | Return types, own vs borrow, stream / future |
| Side-effects | What can it change outside itself? | Imports, one per capability |
| Errors | Which failures does it deliberately return? | result<T, E> with a typed E |
Every component is a reactor: each export is a reaction to something (handle a request, run, on-message). Design components as handlers that are given work, not scripts that fetch it. The world is the whole contract: exports say what starts it, imports say what it may do. Traps mean bugs or violated preconditions; expected failures belong in the signature.
A good WIT API is strictly decoupled (names a capability, not a vendor), virtualizable, mockable (a test double is just another component implementing the interface), and portable (maps cleanly to any language: no exceptions, callbacks, pointers, OS paths, or threads).