Endive 1.0: WebAssembly on the JVM, Now a Bytecode Alliance Project

dustingetz1 pts0 comments

Endive 1.0: WebAssembly on the JVM, Now a Bytecode Alliance Project | Endive

Skip to main content<br>We're excited to announce Endive 1.0 , the first release of the project under the Bytecode Alliance. Endive is a pure-Java WebAssembly runtime with zero native dependencies, continuing the work started as Chicory. For background on the move, see the announcement article. If you're migrating from Chicory, the migration guide has you covered.

WasmGC Host Integration​

The Java garbage collector now manages WasmGC objects. Structs, arrays, and externref values that cross the Wasm/Java boundary are standard Java Objects on the JVM heap. No separate GC store, no manual reference tracking. They get collected when unreachable, just like any other object in your application.

The annotation processor supports externref as plain Object, so host functions work naturally with GC types.

If you use WasmGC types at the host boundary, your code will need a small update. Here's what changed.

Calling exports that use GC types​

Use applyWithRefs instead of apply. It returns a CallResult with separate accessors for numeric and reference results:

// Before: not possible, GC refs were opaque ints

long[] result = export.apply(args);

// After: GC refs flow as Java Objects

CallResult result = export.applyWithRefs(new long[]{42, 10}, null);

WasmStruct point = (WasmStruct) result.refResult(0);

int x = (int) point.field(0);

Calling apply() on a function that involves GC types will throw.

Building structs and arrays​

Old constructors are deprecated. Use the builder:

// Before

var struct = new WasmStruct(typeIdx, new long[]{1, 2});

// After: add fields in declaration order

var struct = WasmStruct.builder()

.typeIdx(typeIdx)

.addField(42) // field 0: numeric

.addFieldRef(someRef) // field 1: reference

.build();

int x = (int) struct.field(0); // read numeric field

Object r = struct.fieldRef(1); // read ref field

WasmArray follows the same pattern with addElement() / addElementRef().

Host functions receiving GC types​

Override applyWithRefs on WasmFunctionHandle:

WasmFunctionHandle myFunc = new WasmFunctionHandle() {

@Override

public CallResult applyWithRefs(Instance instance, long[] args, Object[] refArgs) {

WasmStruct input = (WasmStruct) refArgs[0];

// ... process the struct

return CallResult.of(new long[]{result}, null);

};

See #55 for the full set of changes.

Tail Call Optimizations​

Community-contributed fixes have improved tail call correctness, and the compiler now optimizes tail-call dispatch by eliminating unnecessary stack frame allocation. CPython 3.14, which adopted tail calls in its interpreter loop, is the main beneficiary.

Migrating from Chicory​

For most users, migrating is a find-and-replace. Maven coordinates move from com.dylibso.chicory to run.endive, Java packages move from com.dylibso.chicory.* to run.endive.*, and two exception classes have been renamed (ChicoryException to WasmEngineException, ChicoryInterruptedException to WasmInterruptedException). The migration guide covers the full list, including Maven plugin goals, system properties, and CLI binary names.

If you use WasmGC types at the host boundary, see the section above.

What's Ahead​

Community members have already started prototyping Component Model support at endive-cm. Anyone interested is welcome to contribute. Follow #52 for updates. Cranelift-based native compilation is also in the works, bringing near-native execution speed while preserving the pure-Java packaging experience.

Acknowledgements​

Thank you to every contributor who has shipped code, reported bugs, tested pre-releases, and pushed WebAssembly forward on the JVM. The adopters list, from JRuby to Trino, from Bazel to Apache Camel, is the best evidence that this runtime is solving real problems.

Getting Started​

dependencyManagement>

dependencies>

dependency>

groupId>run.endivegroupId>

artifactId>bomartifactId>

version>1.0version>

type>pomtype>

scope>importscope>

dependency>

dependencies>

dependencyManagement>

dependency>

groupId>run.endivegroupId>

artifactId>runtimeartifactId>

dependency>

Documentation | GitHub

We'd love to hear what you're building. Join the conversation on Zulip and let us know how it goes.

WasmGC Host IntegrationCalling exports that use GC types<br>Building structs and arrays<br>Host functions receiving GC types

Tail Call Optimizations<br>Migrating from Chicory<br>What's Ahead<br>Acknowledgements<br>Getting Started

endive types java from host chicory

Related Articles