Skip to main content
Eric Gregory
Eric Gregory
Eric Gregory
||7 min read

Diving into Endive: a wasmCloud host on the JVM

Diving into Endive: a wasmCloud host on the JVM

The Bytecode Alliance recently welcomed Endive, a JVM-native WebAssembly runtime forked from Chicory. Endive carries Chicory's pure-Java approach forward under vendor-neutral stewardship, with a roadmap that includes the Cranelift-based Redline compiler, WasmGC, and the WebAssembly Component Model.

To celebrate, we did the natural thing: we ran wasmCloud on it.

The result is endive-host, an open-source JVM wasmCloud host built by Cosmonic CTO Bailey Hayes on the Endive runtime. It boots, registers as a Host custom resource with the wasmCloud runtime-operator, accepts workload dispatches over NATS, pulls component bytes from an OCI registry, and serves HTTP triggers, all from a single shared JAR.

The whole demo runs end-to-end in under thirty seconds. More importantly, it illustrates something crucial about wasmCloud v2: the host is a contract, not a particular binary. Anything that speaks the runtime-operator NATS API can join the cluster.

A brief primer on Endive

Endive is a fork of Chicory, the pure-Java WebAssembly runtime that Andrea Peruffo and others have been shipping since 2023. Chicory's pitch was always "WebAssembly with no native dependencies on the JVM," and that idea has traveled a long way since then: pieces of JRuby, the pure-Java SQLite (sqlite4j) and PostgreSQL (pglite4j) drivers, a pure-Java QuickJS, and TrinoDB's Python UDFs all run on top of it.

The Bytecode Alliance move gives that work a neutral home. The project's homepage describes Endive simply as "a JVM-native WebAssembly runtime," but there's a lot more on the roadmap: pulling the experimental Redline compiler (Cranelift-backed, via Java's Panama FFM API) into mainline, deeper WASI support, and the Component Model.

For wasmCloud, that last item is the one to watch...but the demo we want to talk about today is built on what Endive can do now, which is execute WebAssembly modules using WASI P1.

A wasmCloud host that doesn't speak WASI 0.2 (yet)

The wasmCloud v2 runtime is normally a Rust binary embedding Wasmtime. endive-host swaps that out for a JVM process embedding Endive, and keeps the rest of the wasmCloud control surface intact: it heartbeats on runtime.operator.heartbeat.<host-id>, accepts workload RPC on runtime.host.<host-id>.workload.{start,status,stop}, and exposes triggers over an Undertow HTTP server.

The demo lives in a make target:

make demo

That brings up Docker Compose (with a K8s API server and the wasmCloud CRDs pre-loaded), NATS, an OCI registry, the wasmCloud runtime-operator, the runtime-gateway, and endive-host itself. A simple hello world module (166 bytes of hand-written WebAssembly text) is pushed to the local registry, applied as a Workload custom resource, and reached over HTTP:

curl http://localhost:8081/hi

The operator picks a Ready host, NATS-publishes a WorkloadStartRequest, endive-host pulls the OCI artifact, registers an HTTP trigger, and the gateway routes traffic to it. From the operator's perspective, this is no different from scheduling onto a Rust host. From the JVM's perspective, the wasmCloud workload is just another module in the runtime.

Now, it's important to emphasize that Endive runs WASI P1 modules today, not P2 components. The Component Model is on Endive's longer-term roadmap, but additional proposals on the core spec work are being prioritized. So while a Workload declaring wasi:http/incoming-handler will happily route to a Wasm module on this host, the body of the call is a JSON-over-stdio shim rather than a real wasi:http host binding. Components built for P2 or P3 will not be invoked end-to-end.

We want to be very clear about that, because the takeaway from this demo is really the contract, not the runtime. The runtime-operator and the wasmCloud workload API don't care whether your host is Rust, Java, or running on an embedded device. All they care about is whether your host shows up on NATS, accepts workload assignments, and reports status.

A small detour through Vert.x

The endive-host repo also includes a second demo that we shouldn't overlook. In examples/vertx-demo, a single Eclipse Vert.x application embeds endive-host-core directly...that is, without NATS, an operator, or Kubernetes itself. The same JVM process serves a few pure-Java HTTP routes alongside two Wasm-backed ones: a hand-written greeter and a Rust-built Markdown renderer that wraps pulldown-cmark.

A POST /render route shows the punch line: a pure-Java handler accepts a request, invokes the Wasm Markdown module in-process, and returns the HTML. Java functions and Wasm functions coexist in the same JVM, on the same router, sharing one event loop. Wasm invocations run on Vert.x worker threads via executeBlocking so they don't stall the event loop.

That pattern is the one to pay attention to if you run a JVM shop. Drop a wasmCloud host into your existing Vert.x (or Spring Boot, or Quarkus) application, and your Java code and your Wasm components share the same network stack, the same secrets management, the same observability pipeline, and the same deployment artifact.

The bigger picture

Endive matters to the Bytecode Alliance because the JVM is one of the largest managed runtimes on Earth, and getting the Component Model into reach of Java developers is a strategic priority.

For wasmCloud specifically, Endive is interesting because it provides a clean second implementation of a host that runs on the operator. Issues with API boundaries tend to show up faster when somebody outside the Rust tree tries to consume them, and building this host on the JVM has already validated the contract end-to-end.

If this work is in your wheelhouse, the next milestone to watch is Endive picking up the Component Model, which would let endive-host drop the WASI P1 shim and run real wasi:http components natively. (WasmGC is the other big roadmap item, part of the story for efficient compilation of JVM-family languages to Wasm guests.) When that lands, wasmCloud-on-the-JVM moves from demo to deployment target.

One small caveat for the brave: Endive isn't on Maven Central yet, so you'll need to clone bytecodealliance/endive and ./mvnw install it into your local Maven cache before make demo will resolve. A published release is expected very soon.

In the meantime, give Endive and endive-host a try, and join the Bytecode Alliance Zulip or the next wasmCloud community meeting to chat with us about it all.

Watch the walkthrough on YouTube.

Try it yourself:

b]:tw-hidden>

Keep up to date

Subscribe to Cosmonic for occasional communication straight to your inbox.