A programming language designed for AI agents, not humans — compiled to WebAssembly so it runs on any machine.
Today, AI agents write software in languages built for human ergonomics — Python, JavaScript, C++ — and inherit decades of ambiguity, undefined behavior, and style debates along the way. machino flips the design goal. It is a language whose primary user is a machine: one canonical syntax, no undefined behavior, contracts and tests baked into the grammar, and compiler errors emitted as structured JSON that an agent can repair against in a tight loop.
It compiles to WebAssembly — the closest thing that exists to a portable, sandboxed, formally specified machine language — so one compiled binary runs identically in browsers, servers, phones, and edge workers.
fn fib(n: int) -> int
requires n >= 0
ensures result >= 0
{
if n < 2 {
return n
}
return fib(n - 1) + fib(n - 2)
}
fn main() {
print(fib(15))
}
test "fib values" {
assert fib(10) == 55
}
The requires/ensures contracts and the test block aren't a framework — they're language syntax, enforced by the toolchain in both the interpreter and the compiled WebAssembly binary. A violated contract in production traps with the exact failing clause:
contract violation: requires 'b != 0' failed when calling 'safe_div'
| Human-first languages | machino |
|---|---|
| Many ways to write the same thing | One canonical syntax — generated code is diffable and predictable |
| Undefined behavior, silent overflow | Every fault is a defined, messaged trap |
| Tests live in external frameworks | test / assert / requires / ensures are grammar |
| Error messages are prose for humans | Stable-coded JSON diagnostics with fix hints (--json) |
| Ambient authority — any code can hit the network | Capability-based: only declared extern fns reach the host |
| Needs a runtime or per-platform build | One .wasm binary, every platform |
The core bet: agents get good at languages with fast, precise, machine-readable feedback. machino's entire toolchain is that feedback loop.
git clone https://github.com/viralcode/machino
cd machino
cargo build --release # zero dependencies, builds in seconds
./target/release/machino run examples/fib.mno
./target/release/machino test examples/sort.mnoNew to machino? Work through the progressive tutorial — hello → contracts → generics → concurrency → native I/O → SMT → deploy:
→ tutorial/ (start here)
Compile to a portable binary and run it anywhere:
./target/release/machino build examples/fib.mno -o fib.wasm
node runners/run.mjs fib.wasm # Node / Deno / Bun
open runners/run.html # or drag the .wasm into a browserThe same .wasm runs in wasmtime, wasmer, Cloudflare Workers — any WebAssembly host that provides the five-function interface in SPEC.md.
This is the workflow machino is built around. Point your agent at docs/agent-guide.md (a paste-into-context doc that teaches any LLM the language zero-shot) and have it run:
machino check program.mno --json # 1. fix until "ok": true
machino test program.mno --json # 2. fix until failed == 0
machino run program.mno # 3. execute
machino build program.mno # 4. ship a .wasmEvery diagnostic has a stable error code, a location, and usually an actionable fix:
{"severity":"error","code":"E043",
"message":"'+' cannot be applied to 'int' and 'float'",
"file":"program.mno","line":2,"col":12,"endLine":2,"endCol":17,
"help":"machino has no implicit numeric conversion; use to_float(x) or to_int(x)"}A new language starts with zero corpus, which is the real moat and the real risk for LLM adoption. machino attacks it two ways:
-
machino synthgenerates random programs and only emits ones that pass the real type checker — every sample in the corpus is verified, compilable machino. Pair each with its interpreter output for (program, behavior) training pairs.machino synth --count 1000 --seed 42 --out corpus/
-
docs/agent-guide.mdis compact enough to sit in a system prompt, so frontier models can write machino zero-shot today, without fine-tuning.
The whole pipeline is ~15,000 lines of dependency-free Rust — small enough to read in a weekend:
| Path | What it is |
|---|---|
src/lexer.rs → src/parser.rs → src/checker.rs |
frontend: newline-terminated grammar, full static typing, stable E0xx diagnostics |
src/interp.rs |
reference interpreter + native runtime: files, stdin, env, TCP sockets (run, test) |
src/wasm.rs |
WebAssembly binary emitter: hand-rolled encoding, closures, threads, and a mark-sweep GC — no LLVM, no external toolchain |
src/wasmgc.rs |
second backend targeting the WASM-GC proposal (build --gc): the host's collector manages memory |
src/mono.rs |
monomorphization: generic templates become concrete functions before codegen |
src/smt.rs |
static contract verification with Z3 (check --verify) |
src/pkg.rs |
the package system: manifest, installer, lockfile |
src/std.mno |
the standard prelude, written in machino itself |
src/synth.rs |
verified-corpus generator |
runners/ |
reference hosts: Node CLI and a drag-and-drop browser page |
tests/cli.rs |
end-to-end suite: wasm-vs-interpreter equivalence on every feature, plus a live HTTP-server test |
Compiled modules use a simple, documented ABI: every value is one wasm value (i64/f64), heap objects live in linear memory behind a 16-byte GC header, and the module imports exactly five host functions (print_*, fail) plus whatever extern fns the program declares. That extern fn seam is the FFI and the capability system — a machino program cannot name any host power the host didn't explicitly provide.
Every compiled binary also carries its own precise mark-sweep garbage collector — about 300 instructions of hand-emitted WASM. Pointer-typed locals are mirrored into shadow-stack frames that the collector scans as roots; collection triggers at safepoints under an adaptive threshold; freed blocks coalesce into a free list. No engine support, no external runtime: allocation-heavy loops run in bounded memory in any stock WebAssembly host.
examples/http_server.mno is a complete HTTP server written in machino: request parsing with the std string library, path routing, 404s, and graceful shutdown. Sockets are capabilities — the program declares the extern fns it needs and the runtime provides them:
machino run examples/http_server.mno 8080
curl http://localhost:8080/hello/world # -> hello, world!The machino run interpreter doubles as a native runtime with files, stdin, environment, CLI args, TCP sockets, and clock — so agents can ship CLI tools and network services directly, the way they'd use node script.js or python app.py.
- Types:
int(i64, checked arithmetic),float(f64),bool,str(UTF-8 bytes),[T], structs, enums,fn(T...) -> Rfunction values — no implicit conversions, ever - Generics:
fn<T: Ord> max2(a: T, b: T) -> Twith call-site type inference, constraint bounds (Eq,Ord,Num,Hash),+for multiple bounds, andwhereclauses — monomorphized at compile time so both backends stay simple. Genericstruct/enumdeclarations can be constructed directly (Box(42),HashMap(...)) - Data modeling: nominal
structs with positional constructors and field assignment, sum types (enum) with pattern matching — including recursive enums (JArr([Json])); genericHashMap(open-addressing,K: Eq + Hash) alongside concreteStrMap/IntMap - Strings: byte APIs (
len/char_at/substr/chr) plus Unicode codepoint APIs (len_cp/char_at_cp/substr_cp/chr_cp) - Pattern matching: exhaustive
matchexpressions over enums and literals with compile-time coverage checks - Closures: lambdas capture enclosing variables by value —
fn(x: int) -> int { return x + n }— compiled to lifted functions + closure objects, GC-managed - Memory: precise mark-sweep garbage collector compiled into every binary; allocation-heavy programs run in bounded memory on any WASM host
- Control flow:
if/else,while,for i in a..b,break,continue,return - Contracts:
requires(checked at entry),ensures(checksresultat exit) — enforced in the interpreter and in compiled WASM, with identical messages;machino check --verifyproves a decidable subset statically with Z3 - Concurrency:
spawn/join_*for shared-nothing tasks;chan_new/chan_send_*/chan_recv_*/chan_closefor typed message passing between tasks (interpreter + linear WASM) - Std prelude, written in machino itself: strings (
split/join/trim/find/…), numbers (sqrt,pow_int,pow_float,floor/ceil/round,parse_int,str_of_float), JSON parse + serialize (json_parse,json_serialize), ISO-8601 time (time_iso,time_from_ms),StrMapandIntMap, sorting — dead-code-eliminated from compiled binaries - Modules and packages:
import "lib/util.mno", namespaced importsimport "geometry.mno" as geo(thengeo::dist(...),geo::Point,geo::Quadrant::First), plus a package system —machino pkg add mathx ../mathx(or a git URL), thenimport "pkg:mathx/mathx.mno", with transitive flattening, a lockfile, andpkg publish - Testing:
testblocks withassert, snapshot tests (test "x" expects "1\n2" { ... }compares print output), plusmachino fuzzfor contract-driven property testing - Safety: bounds-checked indexing, trapping overflow and division by zero, block scoping, no nulls, no globals, no undefined behavior
- Interop:
extern fn→ WASM imports, provided by the host (files, sockets, env, clock in the native runtime)
Full details in SPEC.md, the formal grammar in docs/grammar.ebnf, and the diagnostic JSON schema in docs/diagnostics.schema.json.
| Command | What it does |
|---|---|
machino check [--json] [--verify] |
typecheck; --verify statically proves contracts with Z3 (build with --features smt) |
machino test [--json] |
run test blocks, including expects snapshots |
machino run [--trace] |
interpret; --trace streams {"event":"call",...} JSON per user function call to stderr |
machino build [-o out] [--gc] [--native] [--stack-mib N] [--no-cache] |
compile to WebAssembly (cached), or --native → Clang/LLVM host executable |
machino fmt [--check|--stdout] |
canonical formatter; refuses any edit that would change the token stream |
machino query file.mno [name] |
machine-readable signatures, generics, contracts of every top-level item |
machino fuzz [--runs N] |
random-input property testing driven by requires/ensures |
machino synth |
generate a verified training corpus |
machino pkg init/add/sync/publish |
package manager + registry client |
Step-by-step from basics to the full language (runnable lessons under
tutorial/code/):
tutorial/README.md — hello, types, control flow, functions, arrays/strings, structs, enums, contracts, generics, closures, HashMap, JSON/stdlib, concurrency, native externs, SMT verify, WASM/GC/AOT deploy, packages, and the agent toolchain loop.
Ready-to-import libraries live in packages/ (~42 packages):
collections, HTTP/CLI, encoding/csv, regex, DOM, plus an advanced math
tier (mathadv, linalg, complex, numeric, signal, bigint, …).
Install with machino pkg add and import "pkg:regex/regex.mno".
See packages/README.md, try packages/demo,
and the package demos examples/pkg_*.mno (math, text/regex, HTTP, DOM, science).
DOM: packages/dom (+ events/layout) and packages/vdom;
browser host runners/dom_host.mjs. Databases:
packages/db — memory, sqlite, mysql, postgres, mongo
(CLI-backed on the host; memory always works).
Curated demos live in examples/. A 100-file language corpus (each with main + test blocks) lives in test/ex_*.mno. Larger HTTP services also sit under test/.
./target/release/machino run examples/neural_net.mno
./target/release/machino test test/ex_073_bfs_graph.mno
./target/release/machino run test/weather_api.mno 8092| File | What it shows |
|---|---|
examples/hello.mno |
Smallest program |
examples/fib.mno |
Recursive Fibonacci + contracts + tests |
examples/sort.mno |
Arrays, index assignment, sortedness helper |
examples/structs.mno |
Nominal structs with reference semantics |
examples/enums.mno |
Enums and pattern matching |
examples/contracts.mno |
Strings, floats, conversions, contract-guarded math |
examples/generics.mno |
Generic functions, inferred args, constraint bounds |
examples/generic_sort.mno |
Generic sort |
examples/complete_generics.mno |
Broader generics coverage |
examples/higher_order.mno |
First-class fn(...) values |
examples/closures.mno |
Lambdas capturing by value |
examples/concurrency.mno |
spawn / join_* |
examples/json.mno |
json_parse / json_serialize |
examples/stdlib_tour.mno |
Prelude tour: math, IntMap, time |
examples/wordcount.mno |
Text processing with StrMap |
examples/maze_solver.mno |
BFS maze solver |
examples/neural_net.mno |
2-2-1 MLP that learns XOR |
examples/http_server.mno |
Real HTTP server via TCP capabilities |
examples/wasmgc.mno / complete_wasmgc.mno |
WASM-GC backend |
examples/smt_contracts.mno / complete_smt.mno |
SMT-verifiable contracts |
examples/registry.mno |
Package registry client sketch |
examples/namespaces/ |
Namespaced imports (geo::Point, …) |
examples/pkg_math_lab.mno |
Packages: mathadv / complex / linalg / numeric |
examples/pkg_text_pipeline.mno |
Packages: regex / encoding / template / csv |
examples/pkg_http_router.mno |
Packages: httpkit / urlparse / cli |
examples/pkg_dom_ui.mno |
Packages: DOM (virtual + browser WASM) |
examples/pkg_dom_events.mno |
Packages: DOM events + vdom |
examples/pkg_db_demo.mno |
Packages: db drivers (memory / SQL / mongo) |
examples/pkg_mongo_local.mno |
Live local MongoDB fetch via mongosh |
examples/pkg_science.mno |
Packages: statsadv / signal / bigint / geom2d |
Every test/ex_NNN_*.mno typechecks and passes machino test. Run them all with:
for f in test/ex_*.mno; do ./target/release/machino test "$f" || exit 1; done| Range | Topic |
|---|---|
ex_001–ex_010 |
Basics: print, int/float/bool/str, arrays, if, while, for, break/continue |
ex_011–ex_020 |
Functions, recursion, requires/ensures, early return |
ex_021–ex_030 |
Structs, enums, match |
ex_031–ex_040 |
Generics, higher-order functions, closures, Box |
ex_041–ex_050 |
Strings, Unicode codepoints, StrMap/IntMap/HashMap |
ex_051–ex_060 |
JSON, time, float math, hash |
ex_061–ex_075 |
Algorithms: search, GCD, primes, DP, BFS, knapsack, Levenshtein |
ex_076–ex_085 |
Snapshot tests, nested arrays, spawn/join, channels, generic bounds |
ex_086–ex_100 |
Mini apps: Caesar, RPN, perceptron, todos, ledger, tic-tac-toe, Roman, neural forward |
| File | What it is |
|---|---|
test/ex_001_hello.mno … test/ex_100_neural_step.mno |
100 self-contained examples (see ranges above) |
test/weather_api.mno |
Live weather HTTP API (Open-Meteo via http_get) |
test/task_backend_service.mno |
Stateful task backend with persistence and auth |
This is v1.3. Capability closeout: turbofish, multi-payload enums, GC spawn of float/str, extern contracts in compiled WASM, interpreter cycle GC, SMT loop invariants, Node TCP, richer DOM events, optional embedded SQLite, stronger regex/math packages.
What 1.3 adds (on top of 1.2):
- Turbofish —
foo::<int, str>(…)at call sites - Multi-payload enums —
E::C(int, str); 65535 variants max - GC spawn — float/str args (struct graphs: linear /
machino run) - Extern contracts in WASM — requires/ensures wrappers around host imports
- Interpreter cycle GC — arena mark-sweep for arrays/structs
- SMT —
while cond invariant e { … }; concat length for strings - Hosts — Node TCP; DOM last-event x/y/key/button/value;
packages/ws - DB —
--features sqliteembeds rusqlite; CLI fallback otherwise --native— Clang/LLVM host executables viaruntime/native(lambdas, spawn/channels, mark-sweep cycle GC,-O3 -flto -march=native,--target/--universal)
Remaining bounds: GC spawn of struct/array graphs; full PCRE/libm; hosted package registry.