eskiu
a self-hosting systems language
Eskiu is a statically typed, compiled systems language. It has the power of C
(explicit memory, direct C interop, native output via LLVM) with the immediacy
of a scripting language: eskiuc run file.esk compiles and executes
in one step. Self-hosting since v0.3.0.

1.Overview
Eskiu compiles through LLVM to a standalone native binary. There is no garbage
collector or managed runtime, so what you deploy is just that binary. The surface
syntax is C-style, so the basics are familiar;
the semantics add sum types, generics with bounds, async/await, channels,
atomics, and an HTTP/2 stdlib. The compiler is written in Eskiu.
hello.esk
extern int printf(string fmt, ...); int add(int a, int b) { return a + b; } int main() { printf("Hello from Eskiu!\n"); printf("2 + 3 = %d\n", add(2, 3)); return 0; }
$ eskiuc run hello.esk
Hello from Eskiu!
2 + 3 = 5
2.Types & matching
Sum types (enum) carry data per variant, and match is
checked for exhaustiveness at compile time, so the compiler rejects a match that
forgets a case.
parse_port.esk
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"); }
3.Generics
Functions and types are parameterised over types, with interface bounds. A bound
like <T: Ord> requires T to implement the interface,
so calls are checked and monomorphised at compile time.
max.esk
interface Ord { int cmp(Ord* o); } struct Coin { int value; int cmp(Coin* o) { if (self.value < o.value) { return -1; } return 1; } } T max<T: Ord>(T* a, T* b) { if (a.cmp(b) > 0) { return a[0]; } return b[0]; } let hi: Coin = max<Coin>(&x, &y); // hi.value == 7
4.Concurrency
async functions return a Future; await
suspends until a value is ready. Typed channels (Chan<T>) move
values between tasks.
sum_squares.esk
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); } // 1, 4, 9 -> 14
5.Toolchain
One binary, eskiuc, drives everything. eskiuc run compiles
and executes in a step; eskiuc build emits a native binary. The stdlib
is bundled, so imports resolve out of the box.
$ eskiuc run app.esk # compile + run in one step $ eskiuc build app.esk -o app # emit a standalone native binary $ eskiuc --version
Try it
Edit the program below and run it. The server compiles it with LLVM and runs it through the same eskiuc run.
Output appears here. Press Run (or ⌘/Ctrl + Enter).
sandboxed: no network, time- and memory-limited, output capped.
6.In production
Eskiu is already used to replace memory-sensitive native code and cryptographic pipelines in shipping software, and to reach hardware a young systems language rarely meets.
| Project | Result | Detail | |
|---|---|---|---|
| ReactVision | ≈85% less memory | AR/VR rendering modules migrated from C++, preserving C ABI interop. | case study |
| INE decoder | 2.5× faster than C | Credential-QR pipeline (AES-256 + RSA-8192), bit-identical to five other implementations. | case study |
| Nintendo 3DS | on-device AR demo | Camera-and-gyroscope AR rendered through ViroCore on citro3d, its logic in Eskiu on the ARM11. | case study |
Early adopters: ReactVision, The Morrow Digital.
7.Install
Grab a prebuilt binary, untar it into /usr/local, and run eskiuc --version.
Windows is experimental: the compiler runs and emits object files; end-to-end linking, exceptions, and networking are still being ported across 0.7.x.
# or build from source $ git clone https://github.com/doranteseduardo/eskiu $ cd eskiu && make
eskiu