NURL
NURL logo
Neural Unified Representation Language

A programming language
built for language models.

NURL is a small, LLVM-backed systems language whose syntax is optimised for the way LLMs read and write code — fixed-arity prefix notation, a one-page LL(k≤4) grammar, and single-owner memory with a static borrow checker (on by default).

v0.39.0current release
25,306lines of NURL in the compiler
804compiler test programs
191stdlib modules
11tested targets
48registry packages

Contributors HindurableHindurable claudeclaude iljasrbiljasrb

Full reference at docs.nurl-lang.org. Driving an LLM agent? The compiler is also exposed as an MCP server — your assistant can build and run NURL directly.

Optimised for LLM token streams

NURL's grammar is designed for the statistical properties of language model output: fixed-arity prefix notation eliminates precedence ambiguity, short dependency windows reduce error propagation during generation, and the full syntax fits on a single page.

See the language reference for the complete feature set, grammar spec, and standard library documentation.

Regular prefix-arity grammar

Every operator has a fixed arity — no infix, no precedence cliffs. About 50 grammar productions (Python has ~100, C ~200), parsed by recursive descent with at most 4 tokens of lookahead.

Local semantics

A token's meaning is derivable from a short window of preceding tokens. No long-range dependencies that break mid-generation.

Single-owner memory

Values auto-drop at scope exit. A static borrow checker (on by default) turns use-after-move, alias double-free, escaping closure captures, interprocedural/return escapes, loop-carried double-frees, and iterator invalidation into compile errors.

Deterministic compiler

Identical source produces byte-identical output. No undefined behaviour, no platform-dependent semantics — the same program means the same thing everywhere.

LLVM-backed

The compiler emits LLVM IR and delegates codegen to clang. One pipeline reaches x86_64, ARM64, RISC-V, Xtensa, and wasm32-wasi — native speed by default.

Self-hosting

The compiler is 25,306 lines of NURL. The bootstrap compiles it with itself twice and requires byte-identical LLVM IR on both rounds before a build is accepted.

Prefix notation, end to end

Everything follows the same shape: OP ARG1 ARG2 …. No operator precedence to memorise, no parser surprises. Every snippet below compiles and runs against the current compiler.

Add two integers function
// One line. No keywords.
@ add i a i b  i { ^ + a b }

// Calls use the same prefix shape.
( add 3 4 )     // → 7
FizzBuzz loops + conditionals
@ 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_int i ) }
        = i + i 1
    }
}
Algebraic data types & pattern match enum + ??
// 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 )
    }
}
Closures & higher-order functions lambda
// Function-type literal: ( @ ret_ty arg_tys )
@ apply ( @ i i ) f i x  i { ^ ( f x ) }

// Closures capture locals.
: i n 5
: ( @ i i ) scale \ i x  i { * x n }

( scale 7 )         // → 35
( apply scale 9 )  // → 45

The full feature set goes well beyond these snippets: generics (including over option types), traits with bounds, match guards, or-patterns, and N-ary payloads, try-operator error handling, defer, channels with select, compile-time const evaluation, and a stackful M:N work-stealing async runtime — all exercised by the 804-program test suite. Full reference: docs.nurl-lang.org/docs/cheat-sheet.

Benchmark results

15 benchmarks, 5 languages, one algorithm each. Every row is gated on all 5 implementations producing the same output. NURL compiles through LLVM -O2. The table is generated from the last CI benchmark run, not edited by hand.

Benchmark NURL C Rust Node Python
lcg20M-step 64-bit LCG + xorshift 37 ms 36 ms 37 ms 1,432 ms 3,898 ms
packet_classifier25M unpredictable branches 56 ms 63 ms 60 ms 157 ms 3,218 ms
ring_write20M ring-buffer stores 40 ms 39 ms 41 ms 58 ms 4,622 ms
histogram_bins20M binned increments 37 ms 37 ms 37 ms 60 ms 4,284 ms
prefix_scan1M 16-wide prefix scans 19 ms 21 ms 20 ms 58 ms 3,242 ms
binary_search5M lower-bound searches 31 ms 28 ms 39 ms 100 ms 4,714 ms
sort_window2M 8-element bubble sorts 38 ms 45 ms 35 ms 163 ms 9,009 ms
bloom_filter4M Bloom-filter queries 13 ms 13 ms 13 ms 2,196 ms 6,065 ms
hash_join5M hash-table probes 23 ms 24 ms 24 ms 2,734 ms 6,503 ms
sieveSieve of Eratosthenes to 10M 34 ms 32 ms 33 ms 76 ms 2,367 ms
fibRecursive fib(35) 25 ms 26 ms 25 ms 101 ms 810 ms
collatzLongest Collatz chain below 100k 14 ms 14 ms 15 ms 54 ms 508 ms
matmul256x256 integer matrix product 18 ms 18 ms 18 ms 65 ms 2,365 ms
json_parse20 parses of a 64 KB document 6.7 ms 6.8 ms 8.4 ms 30 ms 30 ms
nbody500k n-body integration steps 29 ms 31 ms 26 ms 72 ms 1,938 ms

Median wall-clock milliseconds, whole process, lower is better; NURL is highlighted only where it prints a lower number than every other language — two cells showing the same figure are a tie at this resolution, and neither is marked. Same algorithm in every language — each row is timed only after all 5 implementations print the same result, so a cell can never be fast by computing something else. Measured on GitHub Actions ubuntu-latest runner (4 logical cores) with NURL 0.38.0 · clang 18.1.3 · rustc 1.97.1 · Node 22.23.2 · Python 3.12.3, generated 2026-08-11 from commit 8caaa95. Reproduce it with ./bench/bench.sh; sources, compile times, the correctness gate and the process-start-up floor are in bench/.

Target platforms

The compiler emits target-agnostic LLVM IR. Each platform below has been built and tested — desktop and server targets are available in the playground, embedded targets run on real hardware.

Linux x86_64native · CI every push
Windows x86_64.exe · playground
macOS (x64 + ARM64)Mach-O · tested · playground
FreeBSD x86_64FreeBSD 14 VM · release archive
WebAssemblywasm32-wasi · in-browser
Linux ARM64musl + glibc · playground
Linux RISC-V 64static musl · playground
Unikernel (x64 · ARM64 · RISC-V)boots as its own kernel · CI every push
Milk-V Duoriscv64 C906 · on-device
ESP32 (Xtensa)flashed & verified
ESP32-C3/C6RISC-V firmware ELF

Embedded is real, not aspirational. A NURL HTTP file server runs on a Milk-V Duo — a $5 RISC-V board with 29 MB of RAM — cross-compiled as a static musl binary. On ESP32, NURL code flashed to an ESP32-D0WDQ6 drives GPIO directly through memory-mapped register writes, verified over serial; the RISC-V ESP32-C3/C6 family links with stock LLVM. Sources: duo/ and examples/esp32/.

The browser playground compiles to wasm32-wasi and runs the result directly in your tab, and its /build_target endpoint cross-compiles downloadable binaries for Linux (x86_64 / ARM64 / RISC-V), Windows, and macOS (x86_64 + ARM64). The self-hosting compiler itself also builds to wasm, so the entire toolchain can run in a sandbox.

A NURL program can boot as its own kernel. The playground's /build_unikernel endpoint links your program freestanding — no host OS, no libc — into a bootable image for x86_64 (QEMU microvm, Firecracker, cloud-hypervisor) or AArch64 (QEMU virt), boots it server-side, and shows you the guest console. RISC-V 64 boots in the repository's QEMU gate. Pure-NURL TCP/IP and TLS run inside the guest. Sources: unikernel/.

191 stdlib modules, batteries included

Not stubs — production-hardened modules with their own test programs, leak-checked under AddressSanitizer.

Network

Distributed systems (secure p2p overlay, STUN, NAT traversal, DERP relay, SWIM membership, CRDTs). HTTP/1.1 and HTTP/2, both client and server. WebSocket, MQTT 5.0, SMTP, Unix sockets, UDP, TCP/TLS.

Data

JSON, TOML, YAML, XML, MessagePack, CBOR, and CSV with a unified serde layer. PostgreSQL (binary protocol, async, LISTEN/NOTIFY, COPY) and SQLite (transactions, WAL, authorizers) clients.

Concurrency

A stackful M:N work-stealing async runtime written in NURL, plus OS threads, mutexes, condition variables, channels with select, and atomics.

Core

Vec, HashMap, OrdMap, BTree, LRU Cache, Bitset, exact fixed-point decimal, arbitrary-precision integers, regex, SHA-1/256/512, MD5, BLAKE3, gzip, tar, UUID, time, paths, processes, signals.

AI-native

An Anthropic API client (streaming + tool use) and full MCP support — stdio and HTTP servers, client, sessions, registry. NURL programs can be agents and serve agents.

Tooling

LSP server, VS Code extension, nurlpkg test/bench runner, tools/repl, nurldoc, nurlfmt formatter, --lint pass, DWARF debug info (--g), and a differential fuzzer.

Projects

The programs written in NURL that compile and run against the current release.

The compiler itself!

25,306 lines of NURL compile NURL. Every release must reproduce its own LLVM IR byte-for-byte through two self-compilation rounds — a fixed point, not a checksum.

A Game Boy emulator

Complete DMG emulation: passes Blargg's cpu_instrs and instr_timing, renders dmg-acid2 pixel-perfect, and plays Tobu Tobu Girl with the full 4-channel APU — compiled to wasm, running in your browser.

The playground backend

play.nurl-lang.org is a NURL program: HTTP server, build orchestration, the MCP endpoint, and the package registry — all served by the language's own stdlib.

64 examples

From an Enigma machine and Game of Life to a distributed Push-To-Talk voice app, an HTTP/2 client, MCP servers, a Claude-powered agent, and a C64 emulator.

Getting started

Step 1 · Easiest

Try it in the browser

An online editor with examples, build, and run — everything compiles to WebAssembly and runs locally in your tab. Cross-compile downloads for six native targets included.

Open the Playground
Step 2 · Install

One-line install

Download a prebuilt toolchain — compiler, package manager, and stdlib — for Linux (x86_64 / arm64), FreeBSD (x86_64) or Windows. See the install guide for prerequisites and options.

Linux / FreeBSD
curl -fsSL https://nurl-lang.org/install.sh | sh
export PATH="$HOME/.nurl/bin:$PATH"
nurlpkg install nq && echo '{"a":1}' | nq .a
Windows (PowerShell)
irm https://nurl-lang.org/install.ps1 | iex
$env:Path = "$env:USERPROFILE\.nurl\bin;$env:Path"
nurlpkg install nq; echo '{"a":1}' | nq .a
Latest release
Step 3 · Local build

Clone and bootstrap

The only build dependency is clang (LLVM 15+) — no Python, no make, no cmake. 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.nu && ./fizzbuzz
View on GitHub
Step 4 · Editor

Syntax highlighting + LSP

A VS Code / Windsurf extension lives under tooling/vscode-nurl/, backed by a real LSP server with diagnostics and references. The playground ships the same Monaco tokenizer.

Get the extension

48 packages, one command away

reg.nurl-lang.org is the package registry — 299 published versions of real libraries and tools, not placeholders. Semver ranges in nurl.toml, a lockfile for reproducible installs, and a signature on every tarball that nurlpkg checks before it unpacks anything.

Find, install, publish
nurlpkg search whisper   # search
nurlpkg install nq       # program → your PATH
nurlpkg add tensor       # library → deps/
nurlpkg publish          # your turn
Browse the registry
  • Signed, and verified in pure NURL. The registry signs every tarball with Ed25519; nurlpkg verifies that signature against a pinned public key, and the SHA-256, before a single file is written.
  • Readable before you install it. Every published version gets generated API docs and a file browser on the registry — you can read a package's source without downloading it.
  • Reproducible. nurl.lock pins what you resolved, nurlpkg verify fails on drift, and a bad version can be yanked without breaking the ones that pinned it.
  • Your own packages. Sign in with GitHub, mint a token with nurlpkg login, and nurlpkg publish — with --dry-run to walk every gate first.

nurllama

Run language models locally: pull a GGUF model, chat with it, or serve an ollama-compatible API your existing clients already speak.

whisper

Speech recognition in pure NURL — real audio in, real text out, running OpenAI's Whisper checkpoints as shipped.

onnx

Load a trained ONNX model and run inference on the GPU, written entirely in NURL.

tensor

The n-dimensional array the ML packages share — the reusable ndarray, GPU-backed.

grad

Reverse-mode autograd over tensor: record a tape with ops that mirror its surface, call backward, train.

yoloe

Promptable open-vocabulary object detection and segmentation — a NURL port of YOLOE, on the GPU.

wasmtime

A WebAssembly runtime written from scratch in NURL — no libwasm, no embedded engine.

image

PNG and JPEG decode, encode and raster ops with no native library and no shell-out.

nq

jq-lite: filter JSON on stdin with a small query language. The one-liner in the install block above.

Also published: gpu and gpukit (CUDA driver API + NVRTC, with an OpenMP CPU backend), tls, psql, redis, http, swarm, embed, safetensor, vindex, cli, chart, template, cas and more — the full list, with docs and sources for every version, is at reg.nurl-lang.org.

MCP server

NURL exposes the compiler toolchain as a hosted Model Context Protocol server. Connect any MCP client to build, run, and cross-compile NURL without installing the toolchain locally.

Endpoint

https://play.nurl-lang.org/mcp

Claude Code

claude mcp add --transport http nurl https://play.nurl-lang.org/mcp
MCP setup guide

References

Specifications, documentation, and historical records.

Documentation

Install, compile, and run NURL — guides and reference beyond the README, kept up to date as the language moves.

The README

A complete tour of the language, runtime, and pipeline — the canonical reference document.

Formal grammar

EBNF spec lives in spec/grammar.ebnf. Historical snapshots track the language's evolution.

Changelog

Every release documented in Keep-a-Changelog format with the reasoning behind each fix — currently at v0.39.0.

Roadmap

What's done, what's next. Maintained alongside the source so it doesn't drift from reality.

Package registry

48 packages published and installable with nurlpkg install <name> — browse, search, and read docs on the registry.