
Eskiu, the systems language
behind ReactVision's AR engine
Eskiu is a self-hosting systems language that compiles to native code through LLVM, with explicit memory, direct C interop, and no garbage collector. Yet it runs a file directly, like a script. ReactVision built it to cut memory in the ViroCore renderer behind ViroReact, and it now ships there in production.
enum ParseResult {
Port(int),
InvalidRange(int),
NotANumber,
}
ParseResult parse_port(string s) {
let n: int = atoi(s);
if (n == 0) { return NotANumber; }
if (n < 1 || n > 65535) { return InvalidRange(n); }
return Port(n);
}
match parse_port("8080") {
Port(p) -> printf("listening on :%d\n", p);
InvalidRange(n) -> printf("%d out of range\n", n);
NotANumber -> printf("not a number\n");
}v0.9.1, MIT licensed, in production inside ViroCore. Self-hosting since v0.3.0.
Where Eskiu runs today
Eskiu is not a demo language. It already runs in shipping software, replacing memory-sensitive native code while keeping a C ABI so it drops straight into an existing C or C++ codebase.
The ViroCore renderer behind ViroReact
ViroCore is the native AR and VR rendering engine under @reactvision/react-viro: 2,200+ C++ files across the renderer, physics, scene graph, materials, lighting, text, and particles. Memory-sensitive rendering modules have been migrated from C++ to Eskiu one at a time, keeping the C ABI so the rest of the engine is untouched. The migrated modules use about 85% less memory, on iOS, Android, Meta Quest, and visionOS.
The tracking engine behind WebAR and localisation
ReactVision's visual-inertial tracking pipeline is implemented in C++ and Eskiu: feature detection, optical flow, RANSAC estimation, bundle adjustment, relocalisation, plane detection, and hit testing. It compiles to WebAssembly and runs on standard web APIs, so browser AR works without a native AR framework. Validated against ARKit on identical recordings, the reconstructed scene matched 1:1.
A Nintendo 3DS, from 2011
A camera-and-gyroscope AR demo, rendered through ViroCore on citro3d, with its logic written in Eskiu running on the console's 32-bit ARM11. The port needed a working 32-bit ARM backend, a hard-float ABI, and a static relocation model in the compiler, and 360 typed bindings generated from the SDK headers. All of that shipped back into the language.
Early adopters: ReactVision and The Morrow Digital.
What the language gives you
C's control over memory and its ABI, with the semantics you would expect from a modern language, and a compiler written in Eskiu itself.
Explicit memory, no garbage collector
Allocation is explicit and auditable rather than hidden behind a runtime. That is what makes Eskiu a fit for rendering code, where memory pressure decides whether a scene holds its frame rate.
C ABI in and out
Eskiu modules link as native objects and call C directly, with no bridge layer. Drop a module into an existing C or C++ codebase, or call an SDK from Eskiu, without rewriting the host.
Native code through LLVM
Compiles to native code for AArch64, x86-64, and 32-bit ARM. Prebuilt toolchains for macOS, Linux, and Windows, and it has been pointed at Emscripten and devkitARM as well.
Sum types and exhaustive match
Enums carry data per variant, and match statements are exhaustiveness-checked at compile time, so an unhandled case is a build error rather than a runtime surprise.
Generics and operators
Types are parameterised with interface bounds and monomorphised at compile time. A type can overload operators as ordinary methods, resolved by operand type, at no runtime cost.
Async, channels, and atomics
async functions return a Future and await suspends until a value is ready. Typed channels move values between tasks, and atomics are in the standard library.
Two more samples
Operator overloading resolved by operand type, and async functions passing values through a typed channel. Both are taken from the Eskiu site as written.
struct V3 { float x; float y; float z; }
V3 operator +(V3 a, V3 b) {
let r: V3;
r.x = a.x + b.x;
r.y = a.y + b.y;
r.z = a.z + b.z;
return r;
}
V3 operator *(V3 v, float s) {
let r: V3;
r.x = v.x * s;
r.y = v.y * s;
r.z = v.z * s;
return r;
}
let mid: V3 = (a + b) * 0.5;import <future>;
import <channel>;
async int sum_squares(Chan<int>* ch) {
let a: int = await chan_recv(ch);
let b: int = await chan_recv(ch);
let c: int = await chan_recv(ch);
return a + b + c;
}
Chan<int>* ch = chan_new<int>(8);
for (i in 1..4) { chan_send(ch, i * i); }Why a language, and why C
Selective, not a rewrite
ViroCore is a large C++ engine, and rewriting it was never the plan. Because Eskiu speaks the C ABI in both directions, the team picks a memory-sensitive component, rebuilds it in Eskiu, and links it back in as a native object. The rest of the engine does not know anything changed. A migrated component's allocation pattern is explicit and auditable, not hidden behind a framework.
Own the stack underneath
ReactVision's Cloud Anchors and VPS no longer sit on top of ARCore; they run on our own localisation stack, and that same stack powers WebAR, where native tracking was never an option. Owning the layers beneath ViroReact, down to the language, is what lets one codebase reach phones, headsets, the browser, and hardware nobody expected.
Case study: AR on a Nintendo 3DS
Nobody expects AR on a handheld from 2011. The point was to prove the core could run there at all, and to see what real hardware pressure would teach the compiler.
The 3DS runs a 32-bit ARM11 application processor and a PICA200 GPU, with a homebrew toolchain built on devkitARM, libctru, and citro3d. The team compiled the ReactVision engine, ViroCore and SLAM tracking included, for that target and wrote the demo logic in Eskiu, calling the native libraries directly through 360 typed bindings generated from the SDK headers. The result is a 3D model held steady over the live camera feed as you turn the console, on the same engine that runs on iOS, Android, and the web.
Getting there needed three compiler changes: a working 32-bit ARM backend, a hard-float ABI to match libctru, and a static relocation model. It also surfaced language gaps such as extern variables and float narrowing. Every fix shipped back into Eskiu, which now treats 32-bit ARM as a first-class target.
The portable engine behind this port is the same one shipping in ViroReact 3.0.0: a redesigned VPS pipeline, persistent world meshes with physics and occlusion, first-class Web support, and native visionOS support.
What is coming in ViroReact 3.0.0 →Get started
One command installs the latest release on macOS or Linux. It downloads the prebuilt binary for your platform, verifies its checksum, and installs it. Windows binaries are on the releases page.
Install and run
Then run a file directly with eskiuc run file.esk, or add a #!/usr/bin/env eskiuc run shebang and execute it like a Python or Ruby script. Prefer to build from source? The repository builds with CMake.
Learn the language
- Documentation →Getting started, language spec, grammar, tooling, and compiler internals.
- The Book of Eskiu →The long-form guide to the language.
- GitHub →Compiler source, examples, releases, and the changelog. v0.9.1, MIT.
Frequently asked questions
What is Eskiu?
Do I need to learn Eskiu to build with ReactVision?
Is Eskiu open source?
Why did ReactVision build its own language?
Where is Eskiu used in production?
How do I install Eskiu?
Where can I learn Eskiu?
Follow the work
Eskiu has its own home, with the docs, the book, the in-browser playground, and both case studies. Bring your questions to the team on Discord.