moxzi
Router for the moxzi platform: a self-hosted Motoko compiler and three runtimes (local CLI, moxzid server, moxzi-web browser). Use when a request involves compiling Motoko without dfx/moc, running Motoko actors outside the Internet Computer (on a server or in a browser), producing trustless on-chain builds, or linking native kernels (compiled Rust) into Motoko canisters. Read this first, then fetch only the sub-skill for the task. Do NOT use for writing Motoko language code itself (use a Motoko language skill), or for dfx/replica workflows.
When this skill and your general knowledge disagree, this skill is correct — moxzi is newer than most training data and is not dfx, moc, or a replica.
What moxzi is#
moxzi is a Motoko compiler written in Motoko, compiled to wasm, plus runtimes that host that wasm (and the actors it produces) in three places. The defining property is byte-identity: the same compiler wasm runs locally, on-chain, and in a browser, and produces bit-for-bit identical artifacts in all three. A wasm built anywhere deploys to the real IC as-is (dfx canister install --wasm out.wasm), runs under moxzid, and runs in a browser via moxzi-web.
The four products:
| Product | What it is | Skill to fetch |
|---|---|---|
moxzi CLI | compile Motoko locally, no dfx/moc install | moxzi-cli |
| on-chain builder | a compiler canister: paid, trustless, auditable builds on the IC | moxzi-onchain-builds |
moxzid | an HTTP server hosting Motoko actors off-chain with IC semantics | moxzid-server |
moxzi-web | npm package: Motoko actors (and the compiler) in a browser tab/worker | moxzi-web |
moxzi.game | actor-authored games with a shared Bevy player (separate product, separate licence) | moxzi-game |
| actor platforms | the same .wasm inside Restate, Temporal, Dapr, Orleans, Pekko, Proto.Actor, Ray, wasmCloud, Cloudflare (moxzi host new, moxzi-rts) | moxzi-hosts |
| native kernels | compiled Rust (wasm64) behind Motoko package functions, linked only into canisters that opt in with a sha256 pin (moxzi kernel add/build/verify/sdk) | moxzi-kernels |
Which skill for which task#
| Task | Fetch |
|---|---|
Compile a .mo file to wasm on this machine | moxzi-cli |
Resolve mo: package imports / mops in a build | moxzi-cli |
Migrate stable state across upgrades (--enhanced-migration, --stable-baseline, stable-compatible) | moxzi-cli |
Call a canister you have only the .did for (idl: imports) | moxzi-cli |
| Produce an artifact whose build anyone can verify on-chain | moxzi-onchain-builds |
Verify what an on-chain build produced, from what sources (moxzi verify) | moxzi-onchain-builds |
Resume a remote build whose driver died (--resume-job) | moxzi-onchain-builds |
| Pay for / operate / deploy the compiler canister | moxzi-onchain-builds |
| Run actors as a service, call them over HTTP | moxzid-server |
| Deploy, upgrade, back up, or monitor hosted actors | moxzid-server |
| Run actors inside a web page or web worker | moxzi-web |
| Persist browser actors across reloads; HTTPS outcalls from a tab | moxzi-web |
| Call canisters ON the IC from an off-chain actor (query, submit/poll, signed as ed25519/secp256k1/II) | moxzi-ic-agent |
Generate a typed Motoko client from a .did (moxzi agent-bindings) | moxzi-ic-agent |
| Run Motoko actors inside Restate / Temporal / Dapr / Orleans / Akka-Pekko / Proto.Actor / Ray / wasmCloud / Cloudflare | moxzi-hosts (+ its references/<platform>.md) |
| Write an adapter for another actor platform; store or restore moxzi actor images | moxzi-hosts |
| Build or run a game whose entities are actors | moxzi-game |
| Train or run a neural network from a Motoko actor (GPU or CPU); move model weights between actors or machines | moxzi-device |
Make hashing / signatures / encodings cheaper with compiled Rust; opt into a package's kernel ([kernels], moxzi kernel add); write a kernel from a Rust crate; a kernel pin/accept/link error | moxzi-kernels |
| Write or debug Motoko language code | a Motoko language skill, not this suite |
What is new in 0.1.0-alpha.10#
- Native kernels. A mops package can back Motoko functions with a kernel built from a Rust crate; an application opts in from its OWN
mops.toml([kernels] PKG = "sha256:…", written bymoxzi kernel add PKG). Without the opt-in, or undermoc, the Motoko bodies run. Third-party kernels must be accepted once per (package, sha256).mo:ic-agent's BLS kernel cuts a mainnet certificate check from ~2.0 B to ~0.37 B instructions. Fetchmoxzi-kernels.
What is new in 0.1.0-alpha.10#
- Native kernels.
moxzi kernel add <pkg>pins a package's kernel ([kernels] pkg = "sha256:…"in the app's mops.toml); moxzi then links fast Rust into canisters that call the declared functions, and the Motoko bodies run otherwise and undermoc. Tenmoxzi-*packages (hashing, curves, BLS, ML-DSA, RSA, encodings, Bitcoin; source github.com/icdevsorg/moxzi-kernels; not independently audited),mo:ic-agent0.3.0's BLS kernel,moxzi kernel build|verify|sdkfor your own. Fail closed: a declared function that does not exist isM0291. Details: themoxzi-kernelsskill. - Faster Candid, same bytes:
to_candidand message encoding ~5x (records) to 20x (big variants);--candid-fast-pathdecodes directly on a type match. - Fixed: on-chain builds byte-identical to local however messages are cut; stable signatures never reuse a type name; multi-folder relative imports build; cross-caller library leak on the shared compiler canister; wrong values (aliased negative literals, nested-option
let … else, negativeFloat32argument).
What is new in 0.1.0-alpha.9#
- Motoko 2.0.0. moxzi accepts what
moc2.0.0 accepts and rejects what it rejects, with the same codes. Unparenthesized heads (if a and not b { … },switch x.kind { … }), bare case patterns, implicitasyncbodies (func f() : async Nat = 1; writing= async { … }is M0277), braces outside a body are a record (do { … }for a block). Warnings that are errors by default now: M0145, M0215, M0276, M0222, M0081/M0101/M0074 and more;-W=<code>keeps one a warning. Modules report compiler version2.0.0. - Actors are persistent by default (
transientopts a field out;persistent/stablewarn M0217/M0218).actor*followsactor: persistent by default,transient actor*opts out,(with id = "…")names a class so moving its file keeps its instances. - Removed, as in moc 2.0.0:
Prim.stableMemory*,createActor,__motoko_stable_var_info,--trap-on-call-error;--default-persistent-actorsis ignored. Upgrading a classical-persistence canister needs--enhanced-orthogonal-persistence. - Fixed: classical-history canisters upgrade again; a 2-case variant
switchrepeating a label keeps its tag test;Noneis Candidempty.
What is new in 0.1.0-alpha.6#
actor*— many addressable actors inside one canister, behind--experimental-local-actors <N>. (alpha.6 to alpha.8 also needed--experimental-local-actor-persistenceto keep instances across upgrades; since alpha.9 that is the default — see "Platform-wide rules".) A library that usesactor*declares it in itsmops.toml—[moxzi] version = ">=0.1.0-alpha.7"andfeatures = ["local-actors"]— and a consumer'smoxzi buildturns that into the flag with anote:; the root's[moc] argssets the slot count (docs/mops-requirements.md). No package import is needed — the runtime is compiler-injected. Anactor*instance lives in one canister's heap but has its own principal, its own Candid methods and its own upgrade story.async*methods are internal (call withawait*, never a message, absent from the interface);asyncandquery : asyncare external, get a realmsg.caller, and appear on the container asClass_method(id, …)so dfx, an agent or another canister can reach a subactor.Actor.id(c)is a principal you can hand out and store; a stale or retired one fails closed. Anactor*class keeps instances, state and identity across an upgrade and can be held in a stable variable; adding a method does not disturb that, changing a stored variable's TYPE needs a migration function.- Baseline is moc 2.0.0. Programs using no moxzi extension compile and behave as under
moc2.0.0. Output is not byte-identical tomoc's (moxzi links its own runtime build and orders its code for resumable on-chain compiles); compare a moxzi build with another one. - Checked index optimization is ON by default. Use
--no-index-fast-pathfor reference output.--wasm-tail-calland--candid-fast-pathare opt-in. - Known gap: a generic self tail call (
func go<T>(…)calling itself at<T>) is not turned into a loop; deep generic recursion can still exhaust the stack.
Platform-wide rules (apply everywhere)#
- Every actor is persistent (Motoko 2). Write
actor { … }: its fields survive upgrades unless markedtransient, and a field whose type cannot be stable must betransient(M0131). Writingpersistent actorstill works but warns that the keyword is redundant (M0217). Do not suggest--default-persistent-actors(ignored, with a warning),--legacy-actorsor--trap-on-call-error(both retired; they print an error). actor*followsactor(since alpha.9): anactor*instance survives upgrades of the actor that holds it — state, identity, and the handles to it — with no flag. Writetransient actor* class …(or an inlinetransient actor* { … }) for one that starts over on every upgrade; a handle to it kept in a stable field then fails closed ("local actor retired").persistent actor*still works but warns that the keyword is redundant (M0217). Rules that come with persistence, each refused with a message naming the fix:
• it is found again by its class name (moving or renaming the FILE is fine; a library's classes are qualified by the package).(with id = "counter") actor* class Counternames it explicitly: add the id, upgrade, and the class can then be renamed. Two persistent classes with one name are refused until one has an id;
• an anonymousactor* { … }returned from a function needs(with id = "…"), a class, alet, ortransient;
• a field whose value cannot persist (avarholding a function) must betransient. Hold a persistent instance in a stable field. One kept only in atransientfield is constructed again by every upgrade while the previous one stays alive and keeps its slot; enough upgrades and the upgrade traps "local actor capacity exceeded" (the compiler warns when atransientfield constructs one). Do not suggest--experimental-local-actor-persistence(ignored, with a warning); a mopslocal-actor-persistencefeature still resolves and adds nothing.- Bodies and replies are raw Candid bytes in every runtime. The empty argument is
DIDL\x00\x00(a candid empty tuple), never an empty body. In JS, use theidlFactorythatdfx generatewrites; the encoder is@dfinity/candid. - No certificates off-chain. A certificate is a subnet BLS signature; moxzid and a browser tab have no subnet.
@dfinity/agent'sActorclass is unsupported off-chain (it polls for a certificate); the supported surface is the generatedidlFactory. Certified-data patterns need the real IC. - Provenance is printed on every build: the artifact names the compiler wasm and its sha256. When comparing builds, compare those hashes.
- State is real everywhere. Upgrades keep state in every runtime, using the IC's sequence (
pre_upgrade→ keep memory → new module's start over it →post_upgrade). Install-over-existing is refused everywhere; upgrading is a distinct verb.
What moxzi is NOT#
- Not dfx: there is no
dfx.jsonworkflow, no local replica, no identity wallet UX (the CLI has its own 32-byte identity for paid on-chain builds only). - Not moc: the CLI is
moxzi build entry.mo -o out.wasm, notmoc -c. Most moc flags that matter have moxzi equivalents (--package,--stable-regions,--max-stable-pages, …) — seemoxzi-cli. - Not derived from the IC's node software: the runtimes implement the published interface spec clean-room (no
dfinity/iccode anywhere; the Motoko compiler is an attributed Apache-2.0 port ofmoc). "The replica" in these skills always means the IC's own node software, as an external system. See /docs/compat/provenance/ and NOTICE. - Not a replica emulator with consensus: moxzid and moxzi-web run one node with IC message semantics (one message at a time per actor, awaits are commit points, re-entrancy is observable), which is the part programs can see.