Skip to main content

Tutorial 5 — Same artifact, several runtimes

Goal: demonstrate that the same Fiji component artifact runs under multiple categories of WebAssembly host without re-bundling or re-targeting.

This tutorial reuses the workload from Tutorial 1 — Hello, Fiji.

What you need

  • wasmtime on your PATH.
  • Optionally: Node.js 20+ for the jco host category.
  • The Fiji release tarball extracted, with tutorials/01-hello-fiji/ available.

Category 1 — standalone Wasmtime

The Tutorial 1 path:

cd tutorials/01-hello-fiji
wasmtime run --dir=. ../../components/fiji-jvm-composed.component.wasm HelloFiji
# → Hello from Fiji.

This is the simplest host category — a standalone Wasm component runtime, invoked from the shell.

Category 2 — Node.js via jco

jco transpiles a Wasm component into a Node.js module that the runtime can require.

# Inside a Node project:
npx @bytecodealliance/jco transpile \
/path/to/release/components/fiji-jvm-composed.component.wasm \
--out-dir fiji-component

Then load and invoke the component from Node:

import {instantiate} from './fiji-component/fiji-jvm-composed.js';
const {jvm} = await instantiate();
// Use the jvm interface per the public WIT.

Category 3 — browsers

jco can also target browsers via --target browser. The same component artifact runs in any Wasm-component-capable browser environment, with the same public WIT contract surface.

The release tarball's browser harness lives at tools/browser-harness in the repository.

Category 4 — embedded library

Hosts that link against the Wasmtime Rust crate (or any other component-model implementation) can load the same component as an in-process library:

let component = Component::from_file(&engine, "fiji-jvm-composed.component.wasm")?;
let linker = Linker::new(&engine);
let mut store = Store::new(&engine, ());
let instance = linker.instantiate(&mut store, &component)?;
// Use the jvm interface per the public WIT.

The categorical point

Across all four host categories, the same artifact runs:

  • the same fiji-jvm-composed.component.wasm,
  • the same public WIT contract,
  • the same Java bytecode.

No re-build, no re-bundle, no host-specific variant. The artifact is the contract, and the contract is portable.

Where to next