NURL is a small, regular, LLVM-backed language whose syntax is optimised for the way LLMs read and write code — terse prefix notation, no redundant keywords, and a grammar that fits on a single page.
Driving an LLM agent? The compiler is also exposed as an MCP server — your assistant can build and run NURL directly.
Existing languages were shaped by human ergonomics. NURL drops the parts that exist only for humans and keeps what matters for correctness and compilation.
Every construct is encoded in the fewest tokens that preserve full meaning. Less context burned on punctuation, more on the actual problem.
One way to do each thing. The same construct always parses the same way, so generators don't have to remember exceptions.
A token's meaning is derivable from a handful of preceding tokens. No long-range dependencies that break mid-generation.
Identical source produces byte-identical output. No undefined behaviour, no platform-specific surprises — code does what it says.
The compiler emits LLVM IR and delegates codegen to clang. You get optimisation and portability for free, native speed by default.
The compiler is written in NURL itself. Bootstrap runs it twice over its own source and requires byte-identical IR before accepting the build.
Everything follows the same shape: OP ARG1 ARG2 …. No operator precedence to memorise, no parser surprises, no hidden costs.
// One line. No keywords.
@ add i a i b → i { ^ + a b }
// Calls use the same prefix shape.
( add 3 4 ) // → 7
@ fizzbuzz i n → v {
: ~ i i 1
~ <= i n {
: b d3 == 0 % i 3
: b d5 == 0 % i 5
? & d3 d5 { ( nurl_print `FizzBuzz\n` ) }
? d3 { ( nurl_print `Fizz\n` ) }
? d5 { ( nurl_print `Buzz\n` ) }
{ ( nurl_print ( nurl_str_int i ) ) }
= i + i 1
}
}
// Tagged enum: sum type with payloads.
: | Expr {
Num i
Add *Expr *Expr
Mul *Expr *Expr
}
@ eval *Expr e → i {
^ ?? . e 0 {
Num n → n
Add l r → + ( eval l ) ( eval r )
Mul l r → * ( eval l ) ( eval r )
}
}
// Function-type literal: (@ ret_ty arg_tys)
: (@ i i) square \ i x → i { * x x }
( square 7 ) // → 49
// Pass closures to higher-order helpers.
@ apply (@ i i) f i x → i { ^ ( f x ) }
An LLM pays for every token it reads and writes. NURL drops boilerplate without losing information — the compiler still produces fully-typed native code.
| Language | Sum 1…N — approx. tokens | Runtime | Targets |
|---|---|---|---|
| Python | ~46 | Interpreted | Host platform |
| C | ~30 | Native | Many (per port) |
| NURL | ~13 | Native (LLVM) | Any LLVM target |
The compiler emits LLVM IR. Any backend clang supports is reachable in principle — the platforms below ship with build scripts and are tested on every release.
The browser playground compiles your code to wasm32-wasi
and runs it directly in the page — no install, no server-side execution.
The self-hosting compiler also builds to wasm, so the entire toolchain
can run in a sandbox.
Three paths, in order of friction.
An online editor with examples, build, and run — everything compiles to WebAssembly and runs locally in your tab.
Open the PlaygroundRequires Python 3 and clang. The build script bootstraps the self-hosting compiler twice and verifies byte-identical IR.
git clone https://github.com/nurl-lang/nurl cd nurl ./build.sh ./nurl.sh examples/fizzbuzz.nuView on GitHub
A VS Code / Windsurf extension lives under tooling/vscode-nurl/. The playground ships the same Monaco tokenizer, so you'll feel at home in either.
NURL exposes the entire compiler toolchain as a hosted Model Context Protocol server. Any MCP-aware client — Claude Desktop, Claude Code, Cursor, Windsurf, Zed — can read the docs, browse examples, and build native or wasm binaries on your behalf. Nothing to install locally.
Add it as a remote MCP server in one command.
claude mcp add --transport http \ nurl https://play.nurl-lang.org/mcp
Drop into the client's mcpServers block.
{
"mcpServers": {
"nurl": {
"type": "http",
"url": "https://play.nurl-lang.org/mcp"
}
}
}
Open Settings → Connectors → Add custom connector and paste the URL above. Streamable HTTP transport, no auth needed.
Open connectors →nurl_coding_assistant primes the model with the grammarPointers into the repository for the curious.
A complete tour of the language, runtime, and pipeline — the canonical reference document.
EBNF spec lives in spec/grammar.ebnf. Historical snapshots track the language's evolution.
Curated .nu programs that the playground surfaces — fizzbuzz, calculators, ASCII demos, agent hosts, and more.
What's done, what's next. Maintained alongside the source so it doesn't drift from reality.