the two code characters — each a char, together codecode

each one is a char — together they spell code

A tiny, from-scratch language with exactly six value kinds and no type keywords anywhere. This page runs the real interpreter, compiled to WebAssembly — no server, no install, no mock.

number string boolean null array object
why code

Small on purpose

Every feature is deliberate. What isn't here — functions, else, while, type keywords, mutation of constructed values — is absent by design, not by accident.

Six value kinds

number, string, boolean, null, array, object — exactly JSON's. No type keywords anywhere in the language.

Bindings, not types

let x = … creates a name. It's untyped and always reassignable — even to a different kind.

In your browser

The actual interpreter, compiled to WebAssembly. What you see is the real thing — no mock, no server.

Two backends

Interpret with code run, compile to a native binary with code build — same behavior, enforced by tests.

Particles

Point { "x": 1 } is an object with a _class tag — dispatched by emit, no schema required.

Loops & conditionals

loop x over arr, if, and break. No while, no else — ever.

playground

Write it. Run it. Here.

The editor talks straight to the WebAssembly interpreter. Press Run (or Ctrl/⌘ + Enter), or turn on auto-run to run as you type.

live in your browser · WebAssembly
Source
Result

        
examples

Every feature, proven

These are the real test fixtures from the repository — each one is run against both backends in CI. Click any card to load it into the playground.

take it with you

Beyond this page

The playground is the same interpreter you can ship yourself. Two packages cover the two directions: embed code in your web app, or give your native program handlers written in Rust.

npm · browser & node

code-wasm — run code in any JS host

The real parser + interpreter as a small WASM bridge. One call per program, synchronous results, and third-party modules as plain JS callbacks.

1 install
# bundler (Vite, webpack, Rollup…)
npm install code-wasm

# …or straight from a CDN, no build step
import init, { run } from "https://esm.sh/code-wasm";
2 run programs
await init();
console.log(run("let a = 5\nassert a = 5\n"));
// "a = 5\n" — final bindings, like `code run` stdout
3 link modules from your app
const modules = {
  math: {
    dispatch(particleJson) {
      const p = JSON.parse(particleJson);
      if (p._class === "Double")
        return JSON.stringify({ _class: "DoubleResult", value: p.value * 2 });
      throw new Error("unknown handler");
    },
  },
};
run_with_modules(
  'link "math" as m\nemit Double { "value": 21 } to m get r\n' +
  "assert r.value = 42\n",
  modules,
);

Everything crosses that boundary as JSON strings — a module backed by a plain function works exactly like one backed by a real .wasm file. All modules must be provided up front: link resolves before the program starts.

crates.io · rust → .so

code-native — write native modules in Rust

Safe builders over the real ABI, plus the runtime linked in for you — no checkout of this repo needed. Your crate builds into a .so that both code run and code build accept.

1 set up the crate
# Cargo.toml
[lib]
crate-type = ["cdylib"]

[dependencies]
code-native = "1.0"
2 implement two exports
use code_native::*;

#[no_mangle]
pub extern "C" fn code_module_abi_version() -> u32 {
    CODE_ABI_VERSION
}

#[no_mangle]
pub unsafe extern "C" fn code_module_dispatch(out: *mut CodeValue, particle: *const CodeValue) {
    match read_field_str(&*particle, "_class") {
        Some("Double") => {
            let v = read_field_number(&*particle, "value").unwrap_or(0.0);
            make_result(&mut *out, c"DoubleResult", |slot| number(slot, v * 2.0));
        }
        other => runtime_error(format!("unknown handler: {other:?}")),
    }
}
3 build & link it from code
cargo build --release   # → target/release/libmymodule.so

-- my_script.code
link "libmymodule.so" as m
emit Double { "value": 21 } to m get result
assert result.value = 42

An optional third export, code_module_vars, makes m.someConst work alongside emit. C (and anything else that produces a C-ABI shared library) uses src/code_abi.h directly — there's no registry to publish a bundle to.