Testing Wasm Component Model Functions with wasmtime run
The May 28, 2025 wasmCloud community call is a short, hands-on session about testing Wasm component model functions. Brooks Townsend demos wasmtime run --invoke — a new flag in Wasmtime 33 that calls any exported function on a WebAssembly component directly from the command line, passing strongly typed arguments via the WebAssembly Value Encoding (WAVE) syntax. That sparks a discussion about bringing the same ergonomics to wasmCloud's wash call. The team then reviews the Q2 2025 roadmap, and Florian Fürstenberg presents a detailed investigation into why an overloaded Hello World component can deadlock the whole application — tracing it to wRPC handshakes, NATS subscriptions, and the host's invocation semaphore.
Key Takeaways
wasmtime run --invoke(in Wasmtime 33) lets you call a named export on a reactor component straight from the CLI — not just the WASI CLIrunentry point — making it easy to iterate on a single component function without standing up a full host- WebAssembly Value Encoding (WAVE) is the syntax that makes this work: booleans, integers, lists, tuples, records, variants, and optionals can all be typed out on the command line and passed as arguments, with typed results printed back
- wasmCloud's
wash callis far more limited today — it supports only HTTP-style invocations or a no-argument function returning a string — and the team wants to adopt WAVE to makewash callflexible enough to invoke any component export - A feature request already exists (open since 2024 and recently reopened) to add richer typed inputs to
wash call; the maintainers had been waiting for WAVE to mature before wiring it in - WASI HTTP is the hard case for any WAVE-based approach because it relies on resources, streams, and async — Victor Adossi sketched a shim/adapter or Wasm plugin layer that could translate a simple textual request into a full WASI HTTP request
- The Q2 2025 roadmap is intentionally scoped small: error-handling docs landed,
wash/NATS update-availability checks and a--natscontrol flag are in flight, a washboard option forwash devis merging, and awashcontext bug was fixed - Florian Fürstenberg showed that overloading a Hello World component breaks the whole app once parallel requests exceed the replica count by a small "magic number" — the wRPC handshake stops completing because response inboxes lose their subscriber
- Brooks tied this to a not-yet-released fix that adds an invocation timeout so a stuck component releases its semaphore permit; Taylor Thomas argued for better NATS flow control instead of unbounded queuing, and the group discussed making the host leaner with swappable plugins
Chapters
- 0:00 — Welcome to the May 28 community call
- 2:39 — The Wasmtime engine and running WebAssembly components
- 5:30 — Demo: wasmtime run --invoke and typed config records
- 12:45 — Passing complex types with WebAssembly Value Encoding (WAVE)
- 15:44 — Runtime dependencies and the limits of stateless testing
- 17:52 — MCP server use cases for running components
- 20:51 — Bringing WAVE-style invocation to wash call
- 25:43 — An existing wash call feature request, reopened
- 28:06 — Can WASI HTTP be expressed over WAVE?
- 38:21 — Q2 2025 roadmap review
- 42:22 — Good first issues and contributing to wasmCloud
- 45:32 — Florian's deep dive: overloading a component breaks the app
- 52:14 — Invocation timeouts, the semaphore fix, and NATS flow control
- 1:04:13 — A leaner host, plugins, and extensibility
Meeting Notes
Demo: Calling Component Exports with wasmtime run --invoke
Brooks Townsend opened with the engine that powers wasmCloud under the hood: Wasmtime, the Bytecode Alliance WebAssembly runtime that wasmCloud embeds as a library to execute components. He highlighted that, because the Bytecode Alliance ships Wasmtime on a near-monthly cadence, a new capability had quietly landed: you can install wasmtime as a standalone binary and invoke WebAssembly modules and now components directly from the command line.
The demo used a tiny component generated from wash new, exporting a single parse-config function that converts the list<tuple<string, string>> shape returned by wasi:config/runtime's get-all into a strongly typed configuration record. Rather than writing unit tests (awkward for a wasm32-wasip2 target that can't run natively) or standing the component up in a host, Brooks called the export directly with wasmtime run --invoke. The --invoke flag tells Wasmtime to call an exported function on a reactor component rather than the WASI CLI run export — exactly the quick-iteration workflow he had long wanted from wash call.
WebAssembly Value Encoding and the wash call Gap
The key enabler is the WebAssembly Value Encoding (WAVE) syntax, which lets you write out complex argument types — booleans, integers, lists, tuples, records, variants, optionals — right on the command line. In the demo, Brooks passed a list of string/string config pairs (one value a stringly-typed boolean) and got back a parsed configuration with correct types, then showed a more elaborate call mixing a string, a number, a boolean, a nested record, and an optional.
By contrast, wasmCloud's wash call only supports an HTTP-style invocation or a no-argument function returning a string — "extremely inflexible," as Brooks put it. The shared takeaway: adopt the WAVE library (apparently easy to import and parse from a string) so wash call can invoke arbitrary component exports with typed parameters, giving developers a consistent experience from local component testing through to calling a running wasmCloud application. The honest caveat is that wasmtime run is stateless, while wash call targets components already running in wasmCloud with real runtime dependencies (key-value, blob storage) — which is precisely where wasmCloud's value lies.
A Pre-Existing Issue, and the WASI HTTP Hard Case
Victor Adossi noted that a feature request for richer wash call inputs has been open since 2024 and was recently reopened (now that the stale bot is gone) — the maintainers had deliberately waited for WAVE to mature before swapping it in. The group also probed whether WASI HTTP could be expressed over WAVE. Victor explained that WASI HTTP leans on resources, streams, and async, which WAVE doesn't represent directly, but a small shim or adapter — or a Wasm plugin that parses a simple, curl-like request (body plus headers) into a full WASI HTTP request — could bridge the gap for the most common interfaces like incoming HTTP and messaging.
Q2 2025 Roadmap and Good First Issues
Brooks walked the Q2 2025 roadmap, intentionally scoped small to keep it focused (not a sign of lower velocity). Completed: Eric Gregory's error-handling docs (reflecting newly added error handling), and a community-contributed feature to show available wash/NATS update notifications, shipping in the next wash release. In progress: a wash dev option to stand up the washboard dashboard; Rabel's PR to replace RPC/control flags with a --nats flag; and Victor's fix for wash dev not respecting a local wash context (thanks to Amanda Cameron for filing it). Brooks also pointed newcomers to the good first issue and ready for work columns — examples, small components, and CLI tooling tasks — as the best on-ramp to contributing.
Florian's HTTP Overload Investigation
Florian Fürstenberg presented a deep dive (with a diagram of the provider context and component context, NATS/wRPC subjects, inboxes, and the application subject) into a bug from the Quick Guide: overloading the Hello World component breaks the entire application — both the HTTP server provider and the component. He found a "magic number" tied to the replica count: at one replica, three parallel requests are fine, four trips the lock mechanism, and five breaks the wRPC handshake entirely because response inboxes lose their subscriber, stalling async execution of further requests. Brooks confirmed the model and explained that wRPC optimizes by sending the payload with the first handshake message — behavior that belongs in the wRPC NATS transport docs and that OpenTelemetry tracing (e.g. via Tempo or Aspire) should surface better.
Brooks connected it to a similar symptom Milan hit weeks earlier with a Hono JS component at max-replica 10, and a not-yet-released PR that adds an invocation timeout: the host spawns export tasks behind a semaphore, and if a future never completes it never releases its permit, so new requests block forever acquiring one — the fix times out and releases the permit (with metrics) when a component exceeds its configured timeout. Taylor Thomas argued the deeper need is real NATS flow control (today the host queues unbounded invocations rather than letting NATS signal a slow consumer), and the conversation widened into making the host leaner with swappable plugins — built-in providers like HTTP server staying simple, with everything else extractable as plugins or, as WASI matures, Wasm plugins granted capabilities like network access. Florian agreed to file an issue for follow-up.
WebAssembly News and Updates
The headline tool in this call is wasmtime run --invoke, available in Wasmtime 33 from the Bytecode Alliance. It pairs with the WebAssembly Value Encoding (WAVE) to let developers call any typed export on a component without writing host glue — a meaningful quality-of-life improvement for anyone building with the component model. On the wasmCloud side, the next wash release bundles update-availability notifications, a --nats control flag, and a wash dev context fix, with a washboard-in-wash dev option and a richer wash call (via WAVE) on the horizon. For deeper background on the runtime that underpins all of this, see the blog post Wasmtime: a standardized runtime for wasmCloud.
What is wasmCloud?
wasmCloud is a CNCF project that lets you build applications using WebAssembly components and deploy them anywhere — cloud, edge, or Kubernetes clusters. It uses the WebAssembly component model to let you write business logic in any supported language (Rust, Go, Python, TypeScript, C#) while the platform handles capabilities like HTTP, messaging, and key-value storage through a pluggable provider architecture. wasmCloud's host is built on Wasmtime and connects workloads over NATS using wRPC, with built-in OpenTelemetry observability and Kubernetes integration. The result bridges WebAssembly's portable, sandboxed execution model and production cloud-native infrastructure.
Topic Deep Dive: The Wasm Component Model
This meeting is a practical tour of the Wasm component model in everyday development. Brooks's parse-config example is component-model native: a WIT-defined function that takes the list<tuple<string, string>> map from wasi:config/runtime and returns a strongly typed record — the kind of typed interface that makes components composable across languages. wasmtime run --invoke and WAVE matter because they let you exercise those typed signatures directly: pass a record, variant, or optional on the command line and read the typed result back, no boilerplate host required. The same typed-interface contract is why bringing WAVE to wash call would unify local testing and live invocation, and why WASI HTTP is the hard case — its reliance on resources, streams, and async sits at the edge of what a flat value encoding can express, motivating shim/adapter and Wasm-plugin approaches. For wasmCloud, the component model is the contract that lets the host schedule, invoke, and observe these typed functions consistently — whether you're iterating locally with Wasmtime or running at scale over NATS.
Who Should Watch This
This call is especially valuable for component authors who want a faster local test loop for typed exports (start with the wasmtime run --invoke demo at 5:30), Rust and polyglot WebAssembly developers curious how WebAssembly Value Encoding represents records, variants, and optionals on the command line (WAVE walkthrough at 12:45), and platform and SRE teams debugging HTTP behavior under load — Florian's overload deep dive and the invocation-timeout/flow-control discussion start at 45:32.
Up Next
Expect follow-ups on a feature request to bring WAVE-style typed invocation to wash call, the next wash release (update notifications, the --nats flag, the wash dev context fix, and a washboard option), and Florian's promised issue on the HTTP overload / wRPC handshake behavior — likely alongside continued work on invocation timeouts, NATS flow control, and a leaner, more pluggable host. Several of these are tracked on the Q2 2025 roadmap.
Get Involved
wasmCloud is a CNCF project and contributions are welcome. Join the community:
- GitHub — star the repo and check out open issues
- Slack — join the conversation
- Community Meetings — every Wednesday at 1:00 PM ET
- wasmCloud Blog — latest news and releases
Full Transcript
Read the complete transcript with speaker labels and timestamps: