Fiji
Fiji is a Java runtime for the WebAssembly component ecosystem.
0.4.x establishes a stable runtime and component contract.
0.5.x aims to make Java a first-class component language rather
than merely a guest running inside components.
What is Fiji?
Fiji is a Java Virtual Machine packaged as a WebAssembly component.
It exposes a public WIT contract (fiji:jvm/jvm@0.1.0) that lets a
host load .class bytes, invoke Java methods, exchange typed
values with Java objects, and tear the VM down — all without
linking against JNI or shipping a native libjvm.
A real Java runtime executes the bytecode.
Works with your existing toolchain
Take the JARs and .class files you already have and run them on
Fiji. Fiji is an additional deployment target for Java code, not
a replacement ecosystem.
- Standard
javacoutput runs unchanged — compile with any JDK 21+javacyou already have. - No Fiji compiler — no
javacwrapper, no Fiji-aware build step. - No annotations — no
@FijiExport, none of that. Your source is unchanged. - No bytecode rewriting — no agent, no instrumentation pass.
- No build plugin — no Maven plugin, no Gradle plugin. Use the plugins you already use.
If it builds on a normal JVM today and respects the boundaries in Constraints, it runs on Fiji tomorrow. Your existing Maven, Gradle, IDE, and CI pipelines work as-is.
One artifact. Every runtime.
Compile once with standard Java tooling. Deploy the same artifact across browser, server, edge, and embedded environments. No per-target build, no runtime-specific variant, no second toolchain.
| Target | What runs |
|---|---|
| Browser | Same .wasm, transpiled for the browser via jco |
| Server | Same .wasm, run under standalone Wasmtime or any native component-model runtime |
| Edge | Same .wasm, on any Wasm-component-capable edge runtime |
| Embedded | Same .wasm, linked in-process via the Wasmtime crate (or any component-model implementation) |
The same Java bytecode, the same component artifact, the same public WIT contract — across all four host categories. See Same artifact, several runtimes for the end-to-end demonstration.
Why Fiji?
Most existing options for running Java in non-Java environments involve a tradeoff that loses something fundamental about Java:
- Compiling Java to a native binary (e.g. AOT image builds) loses the portability story — you get one binary per platform rather than one artifact that runs anywhere.
- Transpiling Java to Wasm directly loses semantic fidelity — reflection, dynamic class loading, and full classpath search rarely survive the translation cleanly.
- Embedding a native JVM via JNI loses the deployment story —
the host must link against
libjvmand ship platform-specific binaries.
Fiji's bet is different: keep a real JVM, package it as a WebAssembly component, and let the host talk to it through a typed WIT contract. The result is one artifact that runs in any component-capable host (wasmtime, jco, browsers via jco), preserves the semantics standard Java tooling already produces, and exchanges typed values with non-Java components without any JNI surface.
Pick Fiji when you want:
- Full Java semantics (real bytecode, real reflection) running in a component-capable host.
- A single artifact rather than per-platform native binaries.
- Typed cross-language interop with Rust, Python, or any other component-capable language — through a WIT contract, not JNI.
What works today
- Run Java workloads (any
.classfiles compiled by a standardjavac) inside a Wasm component runtime. - Exchange typed values (primitives, strings, arrays, object references) between Java and the host via the public WIT.
- Compose Fiji with other Wasm components — give Java code access to non-Java capabilities through component-model interfaces rather than JNI.
The release ships an end-to-end verification path that any consumer can run against their installation.
Where to next
- Install — get Fiji and a supported Wasmtime onto your system.
- Hello, Fiji — the smallest end-to-end demonstration of Java running inside a WebAssembly component.
- Same artifact, several runtimes — run the same component under standalone Wasmtime, Node via jco, and other host categories.
- Public WIT reference — the stable contract consumers bind against.
- Envelope — the positive boundary of the release, organized by category, with empirical evidence for every supported capability.
- Constraints — the negative boundary: workloads that fail at the boundary rather than silently degrading.
- Roadmap — what
0.4.xis, what0.5.xwill be, and where the trajectory continues from there.
Public versus internal
- Public — the WIT contract at
components/wit/fiji-jvm.wit. Consumers bind against the packagefiji:jvm@0.1.0and treat everything documented there as stable for the release line. - Internal — every other component, every other WIT file, all composition pins, and the runtime's internal layout. Treat as implementation detail; subject to change between releases.