Crate: rib-repl on crates.io.
rib-repl is a read–eval–print loop library for WebAssembly components. End users type Rib (implemented by rib-lang); this crate supplies the session, line editor, completion, highlighting, and static checking of each line against the loaded component before the embedder’s invocation hook runs.
Language guide: golemcloud.github.io/rib/guide.html — syntax, literals, and patterns for the Rib lines users type here.
Example: Once the component is loaded, the following will result in 3, if the component exports a stateful increment_and_get method.
>>> let a = instance();
>>> let b = a.increment-and-get();
>>> let c = a.increment-and-get();
>>> b + c
Rust-shaped surface — Rib’s syntax is similar to Rust's to some extent, to make it easy for Rust developers to pick up. Those who are into webassembly and WIT will find familiar constructs like records, variants, lists, option, and result in the same style as Wasm Wave. The syntax is not a full Rust subset; it is designed for interactive exploration of component exports rather than general-purpose programming.
Wasm Wave literals — Concrete values in Rib use the same textual conventions as Wasm Wave (via rib-lang and wasm-wave). Anyone already using Wave or WIT in the Wasm toolchain should recognise record, list, option, result, and scalar syntax without learning a Rib-specific literal format.
Tab completion and argument stubs — The REPL is built around rustyline completion (rib_edit.rs). Besides export and identifier completion, when the user completes a call (for example after typing ( on a resolved function or method), the editor can offer a full argument list filled with type-correct placeholder values: value_generator::generate_value walks each parameter’s WitType and builds a ValueAndType, then formats it with the same Wave-style printing used elsewhere. Those stubs are meant to be edited, not final logic—but they satisfy the WIT signature so exploration starts from a well-typed skeleton.
Single component instance — The embedding keeps one guest Instance (or equivalent) alive for the session unless it explicitly reloads. Each evaluated line runs against that instance, so guest state, linear memory where applicable, and resource handles tied to the instance remain coherent across prompts. This matches common REPL expectations: stateful APIs can be exercised incrementally without reinstantiating on every line.
Names from let carry across lines — If you type let x = …, later lines can use x again, the same way variables work in any REPL. That is ordinary let behaviour, not a separate concept: the session keeps the values you already defined so you do not repeat large literals or constructor calls on every line.
Static checking — rib-lang type-checks input against the component metadata registered for the session. Many errors surface as Rib diagnostics prior to any Wasm export call, reducing noisy trap-driven failures during exploration.
After load, component authors and runtime integrators routinely need to:
- Exercise exports with realistic
record,variant,list, andresultvalues without a new Rustmainper experiment. - Retain one instance while calling constructors, methods, or other stateful exports in sequence.
- Reuse Wasm Wave-compatible value text where possible instead of bespoke string formats.
rib-repl packages those requirements behind RibRepl::bootstrap / RibReplConfig: link the crate, implement ComponentFunctionInvoke, supply dependency loading, and obtain a rustyline-driven loop on top of the same rib pipeline tests may invoke directly.
- Add a
rib-repldependency to your host crate (e.g. Wasmtime CLI). - Then bootstrap a
RibReplusingRibRepl::bootstrapwith aRibReplConfig. This returns aRibReplwhich has all the functionalities required to run the REPL. RibReplConfigwill direct us to implement right traits that gives REPL the ability to load component, call exports etc.
- Syntax-highlighted input (
rustylineand crate-localRibEdit). - Tab completion for exports, variants, enums, and related symbols; call completion can insert Wave-formatted argument lists generated from each parameter’s
WitType(seevalue_generator.rsandrib_edit.rs). - Static typing of Rib source against the session’s component view.
- Stateful sessions: one guest instance for the session. Example:
let x = instance(); let a = x.increment_and_get(); let b = x.increment_and_get(); a + bwill result in3if the component exports a statefulincrement_and_getmethod. - Narrow embedding surface with
riband common error types re-exported fromrib-replso many projects only add one dependency.
Wasmtime may add an optional rib-repl dependency, gate it behind a feature flag.
Although this is yet to be fully integrated, a work is in progress where this was tried out and it looks promising.
All interactive input is Rib source. Use the language guide (linked at the top of this README); the EBNF grammar is in rib-lang README.
Source: github.com/golemcloud/rib.
License: Apache License, Version 2.0 (with LLVM Exception appendix) — see LICENSE in this crate, or the repository root LICENSE.
