A small systems language with a regular prefix-arity grammar, single-owner memory whose ownership rules make safe programs memory-safe and leak-free, deterministic compilation, and LLVM-based codegen.
Project site: https://nurl-lang.org · Live playground & MCP endpoint: https://play.nurl-lang.org

NURL takes a few design positions that are uncommon together:
., &, |, # — resolve their lowering by operand type; see docs/spec.md §4.9/§6.)*T pointers in unsafe code inherit LLVM semantics — spec §4.2, §6.1; out-of-range shifts are rejected at compile time or panic at runtime.)unsafe functions. Every program accepted without an unsafe function of its own is memory-safe and leak-free, data races included (docs/MEMORY.md §6.2): the ownership rules of the single-threaded language (A2.memory_safe, A2.no_leak_end) are mechanically proven sound in Lean 4 (formal/), every hole found across the tree (h01–h388) is closed and held by a probe in tools/fuzz/holes/, and nothing is released by hand.tools/check_diag_coverage.sh).unikernel/README.md.
A reproducible benchmark suite lives in bench/: 20 benchmarks — fifteen implemented five times each (NURL, C, Rust, Node and Python) and five cryptographic kernels in NURL, C and Rust — with every row gated on all of its implementations printing the same result before any of them is timed. bench/bench.sh runs the lot and writes bench/RESULTS.md (run times, compile times, correctness gate, process-start-up floor) plus a machine-readable bench/results/latest.json, which is what nurl-lang.org renders its table from. The bench workflow refreshes both weekly on a fixed CI runner. Numbers are machine-specific, so run the suite locally for figures you can trust. The HTTP-server peer benchmarks are separate: bench/HTTP_RESULTS.md (HTTP/1.1), bench/HTTP2_RESULTS.md (HTTP/2) and bench/HTTP3_RESULTS.md (HTTP/3 over QUIC).
NURL source (.nu)
│
▼
Tokenizer (deterministic, context-free)
│
▼
Parser (LL(k≤4), ≤4-token lookahead)
│
▼
LLVM IR (.ll)
│
▼
clang
│
┌────┴────────────┐
▼ ▼
native wasm32-wasi
(Linux/Win/macOS) (via WASI SDK)
The compiler (compiler/nurlc.nu) is written in NURL itself. The bootstrap runs it twice over its own source and requires byte-identical LLVM IR on both rounds before the build is accepted. Details: docs/BUILDING.md.
Prebuilt nurlc / nurlpkg / nurlfmt binaries, one command — no clang, no build:
# Linux / FreeBSD / macOS
curl -fsSL https://nurl-lang.org/install.sh | sh
# Windows (PowerShell)
irm https://nurl-lang.org/install.ps1 | iex
Then:
nurlpkg install <name> # fetch & build a program from reg.nurl-lang.org
nurl --version # what you have
nurl upgrade # move to the newest release, in place
nurl upgrade keeps everything else in ~/.nurl — your registry token, the model cache, and every program installed with nurlpkg install. (Aliases: nurl update, nurlpkg self-update. Not nurlpkg update — that one is about a project's dependencies.)
For contributors, or to run the bootstrap yourself:
git clone https://github.com/nurl-lang/nurl.git
cd nurl
./build.sh # builds the C runtime, bootstraps, runs tests
./nurl.sh examples/fizzbuzz.nu fizzbuzz && ./fizzbuzz # compile & run a program
The only build-time dependency is clang / LLVM 15+. ./install.sh also sets up the editor extension and language server in one step. Full instructions — prerequisites per OS, manual bootstrap, DWARF debugging — are in docs/BUILDING.md; editor/LSP/formatter setup is in docs/TOOLING.md.
NURL uses prefix notation — the structure is always OP ARG1 ARG2 … ARGN. Types are single letters (i int64, u byte/uint8, f float64, b bool, s string, v void, *T pointer; sized variants i8/i16/i32, u16/u32/u64, f32); operators are sigils (: bind, = assign, @ define, → arrow, . member, ? ternary/option, ?? match, ~ loop/mutability, ! not/Result, \ closure/try, ^ return, # cast, % trait, $ import).
: | Json { JNull JBool b JNum i JStr s }
@ describe Json v → s {
^ ?? v {
JNull → `null`
JBool x → ? x `true` `false`
JNum n → ( nurl_str_int n )
JStr s → s
}
}
Calls always need parens — ( fn args ) is the only call form; a bare identifier is a name lookup. The authoritative grammar is spec/grammar.ebnf and the **normative language reference** (lexical structure, types, statements, expressions, casts) is docs/spec.md.
Single-owner memory with compiler-inserted auto-drop at scope exit — no tracing GC (Rc cycles are collected), no hidden boxing. Bindings are immutable by default (: i x 0; opt into mutation with : ~). The ownership rules — always on, --strict-borrowck to tighten — reject use after move, a borrow or view read after its source ended, escaping closure captures, iterator invalidation and unsynchronised sharing between threads as hard compile errors, without ever changing generated code: every program accepted without an unsafe function of its own is memory-safe and leak-free (docs/MEMORY.md §6.2; the rules for single-threaded code — A2.memory_safe, A2.no_leak_end — are mechanically proven in Lean 4 under formal/, and every hole found so far is closed). The one remaining source-level trap, the n-ary &/| foot-gun, is a hard error by default; --no-strict-arity demotes it to a warning for trees that need to keep building. Full model, the guarantee and its trusted base: docs/MEMORY.md and formal/README.md.
The type system is strong, static, inferred, algebraic (sum types |, product types via structs), with no subtyping and no implicit conversions.
Every push and PR that touches code runs the bootstrap fixed point and the full test corpus on four host platforms and one bare-metal target, not one:
| Gate | Where | What it proves |
|---|---|---|
| Linux x86_64 | ubuntu-latest | Fixed point + full corpus, examples/ frontend gate, nurlfmt canonical-format gate, and ~20 targeted gates (soundness hole probes, CRC-32, XXH64, Zstandard against the zstd CLI, DWARF, HTTP per-request leak, HTTP/2 conformance with h2spec, HTTP/3 + QUIC conformance with h3spec, diagnostic coverage) |
| FreeBSD 14.2 | real VM | The same corpus on a second OS |
| Windows x86_64 | windows-latest | build.bat fixed point + the Windows golden corpus, then nurl.bat builds and runs a program with both the bundled zig and clang |
| macOS ARM64 | macos-14 (Apple Silicon) | ./build.sh stage1 ≡ stage2 fixed point + the full corpus against the same goldens as Linux, plus the examples/ gate |
| Unikernel | QEMU, in CI | The corpus with no libc at all, then the guest booted on x86_64, AArch64 and RISC-V64 — plus the PVH image under cloud-hypervisor |
| Sanitizers | ubuntu-latest | The whole corpus under AddressSanitizer + UndefinedBehaviorSanitizer |
The second OS and the two non-Linux hosts keep the toolchain honest — the shipped nurlc / nurlpkg binaries link only libc and nurl.sh is POSIX sh, so the toolchain runs unmodified on glibc, musl / Alpine, BSD, Windows and macOS. A documentation-only PR (webdocs/**) skips the code gates and runs the docs build instead, one that touches only the proof work in formal/ skips them too, and a PR touching code as well runs everything. Gate list and how to reproduce each locally: docs/BUILDING.md.
One curl | sh installs the toolchain — nurlc, nurlpkg, nurlfmt and the nurl build wrapper. nurlpkg install <name> fetches, builds, and installs programs from the registry at reg.nurl-lang.org. The rest is one command away: nurl-lsp + the VS Code extension come with a source checkout's ./install.sh; nurlpkg install nurl-mcp drives the local toolchain from an LLM agent over MCP; nurlpkg install wasmbuilder compiles NURL to wasm32-wasi locally and nurlpkg install nwasm runs it with a pure-NURL runtime. Details: docs/TOOLING.md.
| Topic | Document |
|---|---|
| Language reference (normative) | docs/spec.md |
| Standard library module guides | docs/stdlib/ |
| Grammar (authoritative) | spec/grammar.ebnf |
| Building, bootstrap & debugging | docs/BUILDING.md |
| Tooling — editor / LSP / formatter / package manager | docs/TOOLING.md |
Canonical source format (nurlfmt) | docs/FORMAT.md |
| Memory model & borrow checker | docs/MEMORY.md |
| Mechanized soundness proof (Lean 4) | formal/README.md |
| Async runtime (fibers) | docs/ASYNC.md |
| Networking & MQTT client | docs/NETWORKING.md |
| Cryptography & TLS (pure-NURL, no OpenSSL) | docs/CRYPTO.md |
| Distributed stack (NAT traversal, overlay, SWIM, CRDTs) | docs/DISTRIBUTED.md |
| HTTP API, playground & MCP server | docs/PLAYGROUND.md |
| Platforms — codegen targets & host OSes (incl. FreeBSD) | docs/PLATFORMS.md |
| Unikernel — a NURL program as its own kernel | unikernel/README.md |
| Known limitations | docs/LIMITATIONS.md |
| Compiler internals (for contributors) | docs/dev/COMPILER_INTERNALS.md |
| Examples catalogue | examples/README.md |
| Roadmap · Changelog · Contributing | ROADMAP.md · CHANGELOG.md · CONTRIBUTING.md |
Why this matters for LLMs: the regular grammar makes generation reliable and errors local, a whole program fits in a context window, and diffs stay small. The concrete vehicle is the public MCP server at https://play.nurl-lang.org/mcp — see docs/PLAYGROUND.md.
nurl/
├── spec/grammar.ebnf — authoritative grammar (versioned snapshots alongside)
├── compiler/
│ ├── nurlc.nu — self-hosting compiler, written in NURL
│ ├── nurlc_lastgood.{nu,ll} — committed bootstrap snapshot (source + IR)
│ └── tests/ — .nu test programs + snapshot runner + golden baseline
├── stdlib/
│ ├── runtime.c — C runtime (I/O, string helpers, FFI surface)
│ ├── core/ std/ ext/ net/ dist/ hal/ — the NURL standard library (239 modules)
│ └── runtime.o, … — runtime objects (build outputs of build.sh)
├── formal/ — Lean 4 mechanized soundness proof (phases A1, A2)
├── packages/ — first-party packages published to reg.nurl-lang.org
├── examples/ — curated .nu programs (see examples/README.md)
├── nurlapi/ — NURL-native container: compiler-as-a-service + playground + MCP
├── unikernel/ — bootable unikernel images (x86_64 / AArch64 / RISC-V64)
├── tooling/vscode-nurl/ — editor extension (syntax + LSP client)
├── tools/ — nurl-lsp, nurlfmt, nurlpkg build scripts & verification gates
├── docs/ — topic documentation (see the table above)
├── webdocs/ — nurl-lang.org documentation site (Fumadocs + Next.js)
├── bench/ — reproducible benchmark suite
├── build.sh / build.bat — full bootstrap + test-suite driver
└── nurl.sh / nurl.bat — compile a .nu file
NURL = Neural Unified Representation Language. File extension: .nu.
Copyright (c) 2026 The NURL Project Developers. Dual-licensed under either of MIT or Apache-2.0 at your option. SPDX identifier: MIT OR Apache-2.0.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual-licensed as above, without any additional terms or conditions.