Lumen type‑checks familiar TypeScript syntax and compiles it straight to a small, dependency‑free executable. No VM, no interpreter, no Node.
curl -fsSL https://lumen-lang.org/install.sh | sh
interface Point {
x: int;
y: int;
}
function distanceSq(a: Point, b: Point): int {
let dx = a.x - b.x;
let dy = a.y - b.y;
return dx * dx + dy * dy;
}
let origin: Point = { x: 0, y: 0 };
let p: Point = { x: 3, y: 4 };
console.log(`distance² = ${distanceSq(origin, p)}`); // 25
Declare the function, name the library, and the compiler links it, with no
bindings to generate and no runtime in between. defer runs cleanup at scope
exit. How the C FFI works →
// @link m
declare function sqrt(x: number): number;
function hypot(a: number, b: number): number {
using _ = defer(() => console.log("computed")); // runs at scope exit
return sqrt(a * a + b * b);
}
console.log(hypot(3.0, 4.0)); // computed → 5
A predictable static subset of TypeScript: no prototypes, no eval,
no dynamic shapes. Each card opens a stop on the language tour, with a sample you can
run in the browser.
int, number, string, bool, records, tuples and enums. Locals and return types infer; nothing is any.
T | null with ??, ?. and flow narrowing across if, guards and field paths. No undefined.
extends, super, access modifiers, accessors, and generics monomorphized at compile time with no boxing.
try/catch/finally with real stack traces, scope-exit defer, and test blocks run by lumen test.
async/await on a native event loop, Worker.run on real OS threads, and a typed EventEmitter<T>.
A package is a URL, compiled in at build time. declare function plus // @link calls C libraries directly.
Ahead-of-time native code with no interpreter to warm up. Whole-process wall clock on one machine against Node 22; the programs, the numbers and their caveats are in bench/.
EventEmitter<T> vs Node's on 10M emitsWhere V8 wins today: loops that allocate millions of throwaway objects, since Lumen has no generational garbage collector. Escape analysis keeps the common cases on the stack; see the benchmark notes for the shape of code that still favours V8.
Compile errors say what's wrong and how to fix it — expected/got types, did‑you‑mean suggestions, caret underlines, and color. Uncaught runtime errors print a real stack trace with your file and line, even across imports.
$ lumen check main.ts
main.ts:4:1: error: 'add' expects 2 arguments, got 1
main.ts:6:1: error: `string` has no method 'toUperCase' — did you mean 'toUpperCase'?
main.ts:8:1: error: 'r' (`string | null`) may be null — check `!= null`
before reading '.length', or use optional chaining `?.length`
main.ts:9:1: error: `if` condition must be `boolean`, got `i32` —
truthiness is not supported; write `x != 0`
$ lumen run app.ts
util.ts:2:14: Uncaught Error: negative input
2 | if (n < 0) throw new Error("negative input")
| ^
at risky (util.ts:2:14)
at process (app.ts:7:3)
at <main> (app.ts:12:1)
$ lumen test app.ts
ok adds
FAIL rounds — expected 4, found 3
at app.ts:21
1 passed, 1 failed
One self-contained binary, no other toolchain required. The script installs
on macOS and Linux (x86_64 and arm64); on Windows, download the .zip from the
releases page.
curl -fsSL https://lumen-lang.org/install.sh | sh
lumen init writes a starter main.ts plus the ambient
declarations and tsconfig.json, so the project is editor- and type-checker-clean
from the first keystroke.
lumen init my-app
cd my-app
lumen compile main.ts && ./main
lumen watch rebuilds and re-runs the program whenever the entry
file or any of its local imports changes:
lumen watch main.ts # rebuild and re-run on change
lumen watch --no-run main.ts # rebuild only
A binary built the plain way links against the host's libc, so it runs on
machines at least as new as the one that built it. Name a target with --target
and ask for --static to get a self-contained binary that runs anywhere:
lumen compile --target x86_64-linux-musl --static main.ts
lumen compile --library-path ./vendor --link gc main.ts
--library-path names a directory to search for a library that
--link asks for, so a vendored C library links without a package manager on the
machine that runs the program.