Skip to content

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.

Component Model and core-module binaries using different ABI layers before converging on one Flow-Like capability and resource boundary

Component ModelCore module
InterfaceWIT interfacesRaw WebAssembly exports
Data exchangeCanonical ABI generated from WITJSON through linear memory
Export namesget-node, get-nodes, run, get-abi-versionget_node, get_nodes, run, optional get_abi_version
Memory handoffGenerated by component bindingsPacked pointer/length values; module alloc and dealloc are optional helpers
Direct TCP / UDP / DNSAvailable through WASI networking when a network capability enables itNot exposed
HTTPWASI HTTP and Flow-Like host bridge, subject to capabilitiesFlow-Like host bridge where the template SDK implements it
Format detectionComponent headerFalls back to core-module loading
Flow-Like resultNode definitions and WasmExecutionResultThe same

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.

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.

A core module exports:

ExportContract
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.

The maintained formats are:

Component ModelToolchain
Rustwasm32-wasip2 and wit-bindgen
GoTinyGo and generated WIT bindings
C++wasi-sdk, wit-bindgen-c, and component wrapping
ZigZig, generated C bindings, and component wrapping
C#.NET WASI tooling
SwiftSwiftWasm, generated C bindings, and component wrapping
Pythoncomponentize-py
TypeScriptcomponentize-js
Core moduleToolchain
AssemblyScriptasc
KotlinKotlin/Wasm with runtime GC and exception features enabled
NimEmscripten backend
LuaEmbedded Lua runtime compiled with Emscripten
JavaTeaVM
GrainNative WASM output
MoonBitNative 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.

NeedChoice
New package and a maintained Component Model template existsPrefer the Component Model
Direct TCP, UDP, or DNS accessComponent Model, with explicit permissions
Existing compatible core-module packageKeep the core module unless migration has a clear benefit
Language only has a maintained core templateCore module
Small computation-only nodeEither; 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.

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.

  1. Copy flow-like-node.wit into the package’s WIT source.
  2. Generate bindings using the destination language template.
  3. Implement the WIT exports instead of raw pointer/length exports.
  4. Replace flat host calls with generated interface calls.
  5. Build a real component and run the template’s interoperability tests.
  6. Publish it as a new package version and re-check all declared permissions.