Skip to content
Cloud Native Pulse
Release v4.2.0 30 September 2026 · 6 min read

npm install for Wasm Components Is Finally Here

Spin · release

Spin logo

Spin, the CNCF sandbox framework for running serverless apps as WebAssembly components, just shipped v4.2.0 — and the headline feature turns the gnarliest chore in component composition into an interactive wizard.

Spin is a framework for building and running serverless apps as WebAssembly components. You write a component in Rust, Go, TypeScript, or Python, compile it to Wasm, and Spin runs it — triggered by HTTP requests, Redis messages, or timers. The pain it removes: running small services without dragging a full container, image build, and manifest ceremony behind every single function. Wasm components start in microseconds, stay sandboxed, and stay tiny.

Who uses it? Developers building serverless APIs, edge workloads, and event-driven services who want functions without the container paperwork. If Kubernetes is your datacenter and containers are your unit of deployment, Spin offers a smaller unit: one Wasm component, one job, one manifest file.

Think of a Spin app as a LEGO build. Each component is a brick. Until v4.2.0, snapping bricks together meant reading a parts catalog written in TOML, knowing every brick’s exact part number (its WIT interface names), and clicking them together by hand. Spin v4.2.0 hires the shop assistant: a guided command that finds the brick, checks that it fits, and clicks it into place for you.

Composing a Spin app used to mean hand-editing spin.toml with the calm confidence of someone defusing a bomb from memory. Now you get a wizard that asks questions instead.

Why care about v4.2.0 specifically? Because spin deps add lands in this release — one command that inspects a Wasm component, asks you a few questions, and wires it into your app. Plus first-class OpenBao support, a genuine SQL-injection fix, TCP socket hardening, and Wasmtime 49 under the hood. Here is what matters.

What’s New in Spin v4.2.0

spin deps add: The Interactive Dependency Wizard

The headline feature implements SIP 024, and it is exactly what it sounds like: npm install for Wasm components. Point it at a local .wasm file, an HTTP URL, a registry reference, or an existing component in your app. It resolves the source, cracks the component open, and inspects what it actually exports — no more WIT archaeology. The full syntax is one line:

code
spin deps add <source> [options]

Then it gets conversational. Here is the registry flow, straight from the SIP 024 spec:

shell
$ spin deps add aws:client@1.0.0

? Which component should the dependency be added to?
> api-server
  worker
  dashboard

? Which interface do you want to import?
> All from aws:client@1.0.0
  aws:client/s3@1.0.0
  aws:client/dynamodb@1.0.0
  aws:client/sqs@1.0.0

Added aws:client@1.0.0 to component 'api-server'

Run `spin build` to generate language bindings for the new dependency.

Notice what happened there: the CLI inspected the component and offered its real interfaces as menu choices. It also handles SIP 023 fine-grained capability inheritance — when the dependency needs capabilities like allowed_outbound_hosts or ai_models, it asks which ones to inherit. And it warns you at add-time if an inherited capability is not configured on the parent, instead of letting you discover that at runtime with an access-denied error. The whole wizard — footgun removed, guardrail installed — ships in PR #3660.

Middleware Detection: The CLI Knows a Bouncer When It Sees One

The wizard’s best trick: it recognizes HTTP middleware components on sight. Middleware — an auth check or logger that processes a request before your app component sees it — gets wired differently from a normal dependency: onto a trigger’s ordered pipeline. When you hand the CLI a middleware component, it switches flows, asks which route it should guard, and slides it into position:

shell
$ spin deps add ./ensure-admin.wasm

Detected HTTP middleware (imports and exports wasi:http/handler).

? Which HTTP route should the middleware be added to?
> /admin/...
  /api/...

In plain English: the CLI read the component’s imports and exports, noticed it speaks wasi:http/handler in both directions, concluded this thing guards doors, and offered to station it at one. You pick the route; the manifest gets updated; the pipeline order is yours to set. Also part of PR #3660.

OpenBao Support: Vault’s CNCF Sibling Gets a Seat at the Table

OpenBao, the CNCF-hosted community fork of HashiCorp Vault, is now a Spin variable provider. If your secrets story needed to stay inside the CNCF family, this is the piece that was missing. And in the interest of honest journalism, here is the entire feature:

code
/// A provider that uses HashiCorp Vault or OpenBao.
#[serde(alias = "open_bao")]
Vault(VaultVariablesProvider),

Two lines of Rust. The existing Vault implementation was solid enough that OpenBao support is essentially a configuration alias — your runtime config can say open_bao instead of vault, and everything else just works, because OpenBao speaks the Vault API. Sometimes the best feature is the one you barely had to write. Landed in PR #3719.

Bug Fixes and Security

The fixes in this release deserve actual attention — one of them is a data-isolation bug. The short version:

  • Azure Cosmos DB key-value store, SQL injection fixed. Keys and store IDs were interpolated directly into Cosmos SQL query text, so a key containing a single quote could break out of the literal and read or match rows it should never see. They are now bound as query parameters. If you run the Cosmos KV backend with user-influenced keys, this is the item on this list with your name on it. PR #3720.
  • TCP socket quota now counted at creation. Sockets that were created but never connected slipped past max_socket_connections and max_total_connections, because quota was only acquired at connect time. On a multi-tenant host that is a resource-limit bypass; quota is now taken the moment the socket exists. PR #3707.
  • Capability matching now speaks semver. The allow-list compared interface versions exactly, so a component importing wasi:sockets/tcp@0.2.9 was denied against a pinned @0.2.6 — and no manifest setting could grant it. Allow-list checks now use semver compatibility, matching the deny-adapter lookup. Silver lining: v4.1.0 was never affected. PR #3722.
  • Aliased imports can no longer slip past denial. A dependency importing one interface under several labels could previously have at most one of those labels denied; now all of them are. PR #3711.

Under the hood, Wasmtime moves to 49.0.1 (PR #3726) and the Rust SDK lands at v7.0.0 (PR #3689), alongside a stack of allocation and TLS-setup performance work. One more thing, purely for comedy: this release page’s changelog is a 1,130-entry monster reaching all the way back to 2023, truncated by GitHub’s 125,000-character limit — and this same release cycle contains the fix for that release-notes pipeline (PR #3690). The changelog gardener finally fixed the hedge while standing in it.

Spin v4.2.0 turns Wasm composition from a TOML memorization exam into a one-command conversation with your terminal — and that is quietly how frameworks grow up.

Learn More

Also on the podcast 1 · Cloud Native Pulse: Episode 1 ▶ Play 00:17:01