Skip to content

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

@afsalthaj

Description

@afsalthaj

Feature

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

wasmtime_repl_example.mov

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:

>>> 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.

>>> 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

It's very easy for developers to press Tab after typing a function name to automatically populate the arguments in correct Wasm Wave syntax. They can then simply edit the generated values instead of having to learn the syntax and type everything manually.
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. 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 can also attach a short video and screenshot of the REPL in action.

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions