bytecodealliance / bytecodealliance/wasmtime

Add an optional typed interactive REPL for WebAssembly Components to the Wasmtime CLI

Open
#13,136 8 comments 9 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
18.6k
Forks
1.8k
Avg merge
1d 18h
Merged PRs (30d)
126

Description

### Feature

Add an optional typed interactive REPL to the Wasmtime CLI for exploring and invoking WebAssembly Components.

https://github.com/user-attachments/assets/e006e346-2481-408d-9a08-b565d648441f

The REPL would be powered by the **`rib-repl`** crate, which provides:

- Static type checking against the component’s WIT metadata *before* any call
- Smart tab completion with auto-generated Wasm Wave argument placeholders based on function signatures
- Syntax highlighting and polished line editing
- Stateful `let` bindings with a persistent component instance across commands

Example session after `wasmtime component repl my-component.wasm`:

```rust
>>> let counter = instance()
>>> counter.increment-and-get()
1
>>> counter.increment-and-get()
2
>>> let another-counter = instance()
>>> another-counter.increment-and-get()
1
>>> counter.increment-and-get() + another-counter.increment-and-get()
5
```

It works especially well with complex WIT types, including resources via dot-method syntax. In the below example `cart` is a WIT resource, and `add-line`, and `line-count` were functions within resource.

While it may sound intimidating to introduce a new language, users can become productive with just a 2-minute read of the basics — specifically how to create an instance and call functions on it. This makes it very easy for developers to quickly experiment with Wasmtime and their components.
By depending on rib-repl, we also get full auto-completion:

Function names
Function arguments (in correct Wasm Wave syntax)

If users don’t know the available function names, they can simply keep pressing Tab to list all exported functions. Typing a function name followed by ( and pressing Tab again will auto-populate the arguments with properly typed placeholders, which the user can then edit as needed.

```rust
>>> let x = instance()

>>> let my-resource = x.cart("foo")
()
>>> my-resource.add-line({sku: "foo", qty: 42})
()
>>> my-resource.add-line({sku: "foo", qty: 42})
()
>>> my-resource.line-count()
2
```

If there is a type mismatch or if not all required arguments are provided, a clear compilation error is shown before any WebAssembly code is executed.
The rib-repl crate does the heavy lifting. On the Wasmtime CLI side, we only need minimal integration with the rib-repl crate.

Here is a few other examples that showcase the use of `option`, `variant`, `enum`, `record`, `result` type etc with REPL

Image

### Benefit
The current Wasmtime CLI excels at one-shot execution (wasmtime run) and serving, but interactively exploring components with rich WIT interfaces remains painful. Developers often end up writing a full Rust host just to test a few calls or understand stateful behavior.
A typed REPL would significantly improve the developer experience by making the Component Model more approachable for:

* Learning and teaching the Component Model
* Quick prototyping, debugging, and interface validation
* Experimenting with stateful components without boilerplate

This directly supports broader adoption of the Component Model, a key focus area for Wasmtime.
Note on maturity: Although the public rib repository is relatively new, Rib has been developed and used in production for a couple of years inside [Golem Cloud](https://github.com/golemcloud/golem). It previously powered the Golem REPL and advanced usage of rib-lang. It was recently extracted into a standalone project so that other runtimes and tools in the wider WebAssembly ecosystem can reuse it. As part of the extraction, we removed all Golem-specific dependencies and simplified the surface area for broader applicability.
The project is backed by the Ziverge + Golem Cloud team, with multiple people actively working in the WebAssembly ecosystem.
Language guide: https://golemcloud.github.io/rib/guide.html

### Implementation

I have already implemented a working prototype in this branch (feature-flagged under rib):
https://github.com/afsalthaj/wasmtime/tree/wasmtime_rib
The rib-repl crate is deliberately designed for easy embedding:

* Implement a small RibReplConfig struct (which encodes how to load the component and provides the invoke hook).
* Call RibRepl::bootstrap(...) to start the REPL session.

The integration is minimal and only re-exports what is needed from rib-repl. I am happy to refine the subcommand name, adjust the feature flag, or make any changes the team prefers.

I am happy to do any refinements needed.

### Alternatives

* Status quo: Continue relying on writing custom host code or one-shot --invoke calls. This works but provides poor UX for exploration and learning.

* Lightweight built-in explorer: Implement a basic interactive mode inside Wasmtime using only wasm-wave literals and the existing Component API. This avoids a new dependency but would offer significantly less polish (no smart typed completion, no syntax highlighting, weaker type checking, etc.).

*Existing external tools: The only other notable component REPL is wepl, which is tied to Wasmtime v17, lacks modern WIT-aware features, and is not designed as an embeddable library.

Rib REPLis currently the most modern and feature-rich option purpose-built for easy integration with Wasmtime (and other hosts). It uses the official wasm-wave crate for value formatting, staying fully aligned with the Component Model. Adding it as an optional, feature-gated dependency strikes the best balance between value and maintenance burden.
I believe this would be a valuable addition that helps accelerate Component Model adoption.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.