Every language gets the same API - the same functions, the same constants - spelled its own way. Pick whichever you already enjoy writing; you are not giving anything up.
You never install a toolchain. Each language has a ghcr.io/notnullgames/null0-cart-<image> docker image with the compiler (or interpreter) and the current null0 bindings baked in, so your project holds nothing but your game.
compiled
Your code becomes main.wasm. These make the smallest, fastest carts.
⚡C
C is the most direct way to write a null0 cart - the API was designed as a C header, and every other language is a wrapper around it. Small carts, no runtime, no surprises.
cart/main.c · null0-cart-c · compiled🦀Rust
Rust carts are no_std and compile straight to wasm. You get the type system and cargo; you give up the standard library, and every null0 call sits in an unsafe block.
cart/src/lib.rs · null0-cart-rust · compiled⚡Zig
Zig talks to null0 with no glue at all - its extern declarations are the wasm imports. Manual memory, comptime, and a very small cart.
cart/main.zig · null0-cart-zig · compiled🐹Go
Go carts are built with tinygo, and the API is CamelCase to match the language. You get goroutines, slices and maps in a cart under a megabyte.
cart/main.go · null0-cart-go · compiled👑Nim
Nim reads a bit like Python and compiles through C, so it is fast and small. A good middle ground if C feels too bare.
cart/main.nim · null0-cart-nim · compiled🌚Nelua
Nelua is a typed Lua that compiles to C. If you already think in Lua but want a compiled cart with no interpreter inside it, this is the one.
cart/main.nelua · null0-cart-nelua · compiled🅰️AssemblyScript
AssemblyScript is TypeScript with wasm types. Nearly the same syntax as a JavaScript cart, but it compiles to a real wasm module instead of shipping an interpreter.
cart/main.ts · null0-cart-assemblyscript · compiled🦉Odin
Odin is a modern take on C, aimed squarely at games. Explicit, data-oriented, and pleasant to read.
cart/main.odin · null0-cart-odin · compiled🌱C3
C3 is C with the rough edges filed off - modules, slices, and defer, while staying close enough that the null0 header maps over almost unchanged.
cart/main.c3 · null0-cart-c3 · compiled🇩D
D carts are built with ldc in -betterC mode: no druntime, no GC, but you keep templates, slices and D’s much nicer syntax.
cart/main.d · null0-cart-d · compiled💠Onyx
Onyx is a small language built for WebAssembly from the start, so a cart is about as simple as it gets.
cart/main.onyx · null0-cart-onyx · compiled🌾Grain
Grain is a functional language that targets wasm directly. It is the most unusual cart to write - numbers cross the boundary as raw wasm values - but a good one if you like ML-family languages.
cart/main.gr · null0-cart-grain · compiled🧡Haxe
Haxe reaches null0 through its HL/C target. Callbacks are closures you assign rather than exports, and there is no try/catch, but you get a mature, batteries-included language.
cart/Main.hx · null0-cart-haxe · compiledλHaskell
Haskell carts are built with wasm32-wasi-ghc in reactor mode. Everything is in IO, and it genuinely works - probably the most surprising thing running on null0.
cart/Main.hs · null0-cart-haskell · compiled🧘Zen-C
Zen-C transpiles to C and builds with wasi-sdk. It is young, and a few functions have plainer signatures than elsewhere to work around a compiler bug, but simple carts are fine.
cart/main.zc · null0-cart-zenc · compiled🧩Jik
Jik also transpiles to C. Its types do not line up with the null0 ABI, so the bindings are a set of extern declarations and C wrappers you copy into your cart.
cart/main.jik · null0-cart-jik · compiled🔧WAT
WebAssembly text format: no language at all, just wasm. Nothing is hidden - a Color is four bytes you write into memory yourself. Worth reading once to see what every other cart compiles down to.
cart/main.wat · null0-cart-wat · compiled🥤Walt
Walt is JavaScript-shaped syntax over raw wasm. Like WAT, you manage memory by hand, but the code is far easier to look at.
cart/main.walt · null0-cart-walt · compiledinterpreted
The interpreter is main.wasm, and your script rides along inside the cart. Bigger files, but nothing to compile and the cart stays readable.
😃JavaScript
JavaScript is the quickest way to try an idea. Your cart ships a QuickJS interpreter inside it, so it is a bigger file than a compiled cart - you are trading size for not having to install anything.
cart/main.js · null0-cart-quickjs · interpreted🐍Python
Python carts run on RustPython baked into the cart. This is a small Python - no standard library - but the language you know, with the null0 API sitting in globals.
cart/main.py · null0-cart-python · interpreted🌙Lua
Lua is the classic game-scripting language, and null0 uses GopherLua so it works inside the host’s interpreter. Plain globals, tables for structs, require for extra files.
cart/main.lua · null0-cart-lua · interpreted🐦Wren
Wren is a small, class-based scripting language with a lovely syntax. The null0 API hangs off a Null0 class, and zero-argument calls are getters.
cart/main.wren · null0-cart-wren · interpreted⚡Cyber
Cyber is a fast, small scripting language. The VM is re-entered for each callback, so your top-level state persists between frames.
cart/main.cy · null0-cart-cyber · interpreted