Component Model vs Core Modules
Flow-Like auto-detects whether a .wasm binary is a WebAssembly Component Model component or a core module. It adapts the binary’s ABI and exposes both as the same Flow-Like node abstraction.
Quick comparison
Section titled “Quick comparison”| Component Model | Core module | |
|---|---|---|
| Interface | WIT interfaces | Raw WebAssembly exports |
| Data exchange | Canonical ABI generated from WIT | JSON through linear memory |
| Export names | get-node, get-nodes, run, get-abi-version | get_node, get_nodes, run, optional get_abi_version |
| Memory handoff | Generated by component bindings | Packed pointer/length values; module alloc and dealloc are optional helpers |
| Direct TCP / UDP / DNS | Available through WASI networking when a network capability enables it | Not exposed |
| HTTP | WASI HTTP and Flow-Like host bridge, subject to capabilities | Flow-Like host bridge where the template SDK implements it |
| Format detection | Component header | Falls back to core-module loading |
| Flow-Like result | Node definitions and WasmExecutionResult | The same |
Component Model
Section titled “Component Model”The repository’s WIT world is flow-like:[email protected]. It imports Flow-Like interfaces for logging, pins, variables, cache, streaming, metadata, storage, models, authentication, HTTP, schemas, images, database operations, and WebSockets.
The component exports node definitions and execution results as strings containing JSON. Language bindings handle the canonical ABI representation, so package code does not manually pack pointers and lengths.
The runtime crate and Rust SDK currently declare numeric ABI version 2, while
several other maintained SDKs still emit 1. The loader records the reported
value but does not currently reject a binary solely because the number differs.
Use the value supplied by the language template rather than hard-coding the
Rust value. The numeric ABI is separate from the WIT package version.
Networking
Section titled “Networking”The component linker provides WASI Preview 2 and WASI HTTP interfaces. Flow-Like host functions check their corresponding capabilities. In the current Component Model linker, any network capability also enables the WASI networking context, so do not assume strict per-protocol isolation between direct WASI socket categories. Package manifest host restrictions are not merged into the installed node’s execution configuration; enforce destination restrictions at the executor or network-policy layer.
An enabled network category is not blanket filesystem or process access.
Core modules
Section titled “Core modules”A core module exports:
| Export | Contract |
|---|---|
get_node() | Returns a packed pointer and length for one JSON definition |
get_nodes() | Returns a packed pointer and length for a JSON definition array |
run(ptr, len) | Reads execution-input JSON and returns result JSON |
alloc(size) | Optional module allocator |
dealloc(ptr, size) | Optional module deallocator |
get_abi_version() | Optional numeric ABI version |
At least one of get_node or get_nodes is required. When alloc is absent, the host uses its bounded allocator.
Core modules call flat Flow-Like host functions. They do not receive direct WASI socket access; network-capable core templates use the Flow-Like HTTP host bridge when their SDK supports it.
Language templates
Section titled “Language templates”The maintained formats are:
| Component Model | Toolchain |
|---|---|
| Rust | wasm32-wasip2 and wit-bindgen |
| Go | TinyGo and generated WIT bindings |
| C++ | wasi-sdk, wit-bindgen-c, and component wrapping |
| Zig | Zig, generated C bindings, and component wrapping |
| C# | .NET WASI tooling |
| Swift | SwiftWasm, generated C bindings, and component wrapping |
| Python | componentize-py |
| TypeScript | componentize-js |
| Core module | Toolchain |
|---|---|
| AssemblyScript | asc |
| Kotlin | Kotlin/Wasm with runtime GC and exception features enabled |
| Nim | Emscripten backend |
| Lua | Embedded Lua runtime compiled with Emscripten |
| Java | TeaVM |
| Grain | Native WASM output |
| MoonBit | Native WASM output |
The binary format does not guarantee identical SDK coverage. Check templates/wasm-capability-matrix.md before depending on a host function in a particular language.
Which model should you choose?
Section titled “Which model should you choose?”| Need | Choice |
|---|---|
| New package and a maintained Component Model template exists | Prefer the Component Model |
| Direct TCP, UDP, or DNS access | Component Model, with explicit permissions |
| Existing compatible core-module package | Keep the core module unless migration has a clear benefit |
| Language only has a maintained core template | Core module |
| Small computation-only node | Either; choose the better-supported template |
Do not wrap a core module as a component only to change the file header. A real migration requires WIT bindings and the component export contract.
Shared runtime behavior
Section titled “Shared runtime behavior”Both formats:
- run in Wasmtime;
- are cached by content and can use precompiled artifacts;
- receive node-specific capability configuration;
- are bounded by fuel, epoch interruption, memory, and timeout controls;
- produce the same node definitions, outputs, execution-pin activations, and error shape.
The ABI layer differs; the permission boundary and Flow-Like workflow model do not.
Migration outline
Section titled “Migration outline”- Copy
flow-like-node.witinto the package’s WIT source. - Generate bindings using the destination language template.
- Implement the WIT exports instead of raw pointer/length exports.
- Replace flat host calls with generated interface calls.
- Build a real component and run the template’s interoperability tests.
- Publish it as a new package version and re-check all declared permissions.