Known limitations
The authoritative consumer-facing constraints document ships with
every release tarball at CONSTRAINTS.md, and lives in source at
dist/CONSTRAINTS.md.
This page is the high-level summary.
What does not work
The component runtime envelope places real limits on what Java code Fiji can execute:
- No AWT / Swing / Java2D — there is no native graphics surface available inside a Wasm component. Workloads that depend on AWT, Swing, Java2D, or any other rendering path fail clearly at the boundary.
- No unrestricted native library loading —
System.loadLibraryanddlopen-style native code loading are not supported. Capabilities that traditionally require native libraries are expected to arrive through composed components, not through dynamic loading. - No unrestricted process spawning —
ProcessBuilderandRuntime.execdo not work the way they do on a host JDK. Workloads that depend on spawning subprocesses fail clearly at the boundary.
What "fails clearly at the boundary" means
Workloads that hit one of the above constraints do not silently degrade or produce subtly wrong results. They fail with a deterministic error at the point the unsupported capability is requested. That's the design — the runtime contract is "stay in the box → works / leave the box → runtime tells you clearly."
This is the trust-protecting boundary: a Fiji release earns trust by making the gaps explicit rather than masking them.
Workflow-preservation philosophy
Fiji's compatibility model is workflow-preserving, not mechanism-preserving:
- The traditional "SQLite means
dlopen()" assumption is mechanism-preserving. - The Fiji-shaped "I want a relational database available through JDBC" assumption is workflow-preserving.
Workflows that preserve their intent while changing their mechanism tend to thrive inside Fiji. Workflows that hard-code the mechanism do not.
When you hit a constraint
When you hit a constraint and feel that what you actually want is preserved (an intent that doesn't require the specific mechanism), the question to ask is: "what assumption am I making, and is there a component-native bridge that satisfies the intent without requiring the assumption?"
The runtime is the box; the bridges into the component world arrive (or do not arrive) over time as the ecosystem matures.
See also
- The full constraint list with examples:
dist/CONSTRAINTS.md - Public WIT contract: Public WIT reference
- Where Fiji is going: Roadmap