Compiles to portable C
U is a systems language where the safe path and the fast path are the same path. Write the obvious code — the compiler handles memory, concurrency, and vectorization. No garbage collector, no data races, no ceremony. LLMs generate correct U on the first try because the defaults are already safe.
// Parameters are read-only by default.
// Shared without a lock, copied without a care.
f describe(cfg: Config) -> S
r => "{{cfg.name}} v{{cfg.version}}"
// +V says: these lanes are independent.
// The C that comes out uses real SIMD.
f scaleAll(arr: [I +V] +R) -> [I +V] +R
r => arr.map(val => val * 3)
Every safety property comes from one system: modifiers on types. No separate borrow checker, no async runtime, no SIMD intrinsics to learn. One mechanism, six benefits.
Stack by default. +R moves a value to the refcounted heap and
the compiler emits the retain and release calls. No pauses, no lifetime
annotations to argue with.
a before a call makes it async — a fiber. No async/await
coloring, no ThreadPoolExecutor. The same function works whether its
input arrives now or later.
+V promises the lanes are independent. The emitted C uses
vector types that become SSE or AVX on x86, NEON on ARM, and WebAssembly
SIMD in the browser. Write it wrong and it's a compile error, not a silent
slow path.
+R(GPU) puts data in device memory and turns a .map() into a
WGSL compute shader. The same kernel runs in the browser through WebGPU and
natively through Dawn — one source, every device.
Parameters can't be mutated. Fields outside your instance can't be mutated.
Shared state goes through atomic << patches. Data races are
compile errors, not runtime crashes.
U emits ordinary C11 with no runtime to install. It compiles with the toolchain you already have, and the same source goes to WebAssembly through Emscripten.
Pick one. The code below is real, and so is the C beside it — both come straight out of the compiler.
No framework, no ORM boilerplate, no threading library. The handler is a function. The query compiles to parameterized SQL. The transaction retries on conflict automatically.
// ── Schema ────────────────────────────────────────── d User : Database.Row name: S email: S score: I // ── Handlers — pure functions: Request in, Response out ── f list_users(req: Request) -> Response users = Database.Query({ store: "users" }) .select(["name", "email", "score"]) .orderBy("score", "DESC") .limit(50) .fetchAll() r => Response({ body: JSON.encode(users) }) f create_user(req: Request) -> Response ! ValidationError body = JSON.decode(req.body) body.name.len < 1 ? x ValidationError("name required") user = User({ name: body.name, email: body.email, score: 0 }) user.save() r => Response({ status: 201, body: JSON.encode(user) }) f award_points(req: Request) -> Response // Transaction: both users update atomically, or neither does << ( sender = Database.Query({ store: "users" }).where("email", "=", req.query["from"]).fetchRow() recipient = Database.Query({ store: "users" }).where("email", "=", req.query["to"]).fetchRow() sender.score < 10 ? x Rollback("not enough points") sender << { score: sender.score - 10 } recipient << { score: recipient.score + 10 } ) r => Response({ body: "transferred" }) // ── Start ─────────────────────────────────────────── f main() -> none serve(8080, { "GET /users": list_users, "POST /users": create_user, "POST /award": award_points })
What the compiler enforces in this code — without a single annotation beyond what you see:
• req is -M (parameter default) — handlers can't corrupt the request
• sender.score read inside << ( ) is a snapshot — retries on conflict automatically
• sender << { score: ... } is an atomic MVCC patch — no lock, no mutex
• Rollback exits the transaction cleanly — neither update applies
• ! ValidationError in the signature — the caller knows exactly what can fail
• The query builder compiles to parameterized SQL — no injection, ever
U is a working reference compiler, not a finished product. The status page is deliberately blunt about which features run, which are simplified, and which are still stubs — every row names its own limits.
The full reference: types, modifiers, memory model, concurrency, error handling, and the reasoning behind each choice.
How u2c is built — parser, linter, code generation, the runtime, and the decisions that shaped them.
Every feature marked Works, Simplified, or Placeholder, with the exact scope and the test that backs it.
Notes on running U in the browser: the WebAssembly path, the playground, and what still has to land.
A short tour that starts at functions and ends with a GPU kernel, with runnable snippets the whole way.
Small, copyable programs that show one idea each — and a link format for sharing your own.