Drop the interpreter, the runtime overhead, and the boilerplate. Festina compiles through LLVM to a real, standalone executable — with SQLite, graphics, audio, and event-driven timers built directly into the language, not bolted on as libraries.
table People { id:int name:text } text func greet(name:text) { return `Hello, ${name}!` } log(greet('Festina'))
$ bin/festina compile examples/greet.f -o greet && ./greet
Hello, Festina!
No imports. No config. No main(). Run this today —
festina.sqlite and the People table are
created and kept in sync automatically, the whole festina
runtime is one native binary, and it needs nothing Python or
JIT-shaped to execute.
Six decisions that shape everything else about the language.
Every Festina program compiles through LLVM to a real executable. No interpreter, no JIT warmup, no runtime shipped alongside your code.
Declare a table, and festina.sqlite is created, migrated, and kept in sync automatically — no ORM, no migration scripts.
A real on-screen canvas (drawRect, on click, …) and real audio playback (loadAudio().play()), backed by Cairo/X11 and ALSA.
Template strings, ternaries, familiar control flow — but int/float never silently mix, and everything is statically typed and checked before it runs.
A compiled program only links what it actually uses — skip graphics and audio in your source, and the binary skips Cairo, X11, and ALSA too.
The fewest dependencies that get the job done, failing loudly and clearly the moment one is actually missing.
$ sudo apt install clang libsqlite3-dev libcairo2-dev libx11-dev libasound2-dev pkg-config $ bin/festina compile examples/hello.f -o hello $ ./hello
Or skip the intermediate binary and just run it:
$ bin/festina run examples/hello.f
Not sure your machine has everything Festina needs?
bin/festina doctor checks every dependency above and
tells you exactly what's missing and how to install it — including
whether festina itself is on PATH yet.
That's the whole loop — see setup.md for the full dependency breakdown, packaged-binary installs, and running the test suite.
int count = 10 text message = 'Hello' bool active = true if active { log(`${message}, ${count} times`) } int func add(a:int, b:int) { return a + b } for int i = 0, i < 10, i++ { log(i) }
int and float never mix implicitly — convert
explicitly with .toFloat() or
Math.floor/ceil/round/trunc. Division and modulo by zero
return null instead of crashing. See the
API reference
for the full language and standard library documentation.
// SQLite -- no setup code, no ORM table People { id:int name:text } arr[People] people = sqlite('SELECT * FROM People') // Graphics -- a real window, opened on first use drawRect(0, 0, 100, 100) on click(x:int, y:int) { log(`clicked ${x}, ${y}`) } // Audio aud music = loadAudio('music.wav') music.play() // Timers setTimeout(showMessage, 1000) setInterval(tick, 500) // Regex, literal syntax 'room 42'.replace(/[0-9]+/, 'N') // Maps -- text-keyed, JS-object-literal-flavored map[int] npcHealths = { 'npc1': 10, 'npc2': 15 } npcHealths['npc1'] = 30 // Config straight from the environment, no extra library text apiKey = environment.API_KEY
Festina, Rust, Go, and Bun on the same small equivalent-logic benchmarks. Not a claim that Festina is faster in general — see benchmark.md for methodology and the full, regularly-refreshed results.
| hello | Run time | Build time | Binary size |
|---|---|---|---|
| Festina | 1.4 ms | 498.9 ms | 1.44 MB |
| Rust | 1.5 ms | 81.9 ms | 3.77 MB |
| Go | 1.2 ms | 157.2 ms | 2.11 MB |
| Bun | 10.6 ms | n/a | n/a |
| fib(32) | Run time | Build time | Binary size |
|---|---|---|---|
| Festina | 7.6 ms | 70.9 ms | 1.44 MB |
| Rust | 7.7 ms | 84.5 ms | 3.77 MB |
| Go | 13.5 ms | 155.3 ms | 2.11 MB |
| Bun | 28.1 ms | n/a | n/a |
| loop_sum (100M) | Run time | Build time | Binary size |
|---|---|---|---|
| Festina | 520.0 ms | 75.1 ms | 1.44 MB |
| Rust | 523.8 ms | 84.9 ms | 3.77 MB |
| Go | 459.8 ms | 151.3 ms | 2.11 MB |
| Bun | 8969.0 ms | n/a | n/a |
Short version: Festina holds its own against Rust and Go on compute-bound native code, and comfortably outruns a JIT on cold single-shot execution — unsurprising for a young optimizer against two of the most mature compiled-language backends around.
The compiler frontend, LLVM codegen backend, and native C runtime are
real and tested. Every claude.md language construct this
project has committed to is implemented end to end, not just parsed.
See
tests/CONTRACT.md
for exactly what's covered, and
todo.md
for what's next (macOS, Windows, HTTP).
| API reference | Full browsable language & standard library docs |
| setup.md | Setup & dependencies |
| security.md | Security & audit history |
| benchmark.md | Benchmarks vs. Rust/Go/Bun |
| todo.md | Roadmap |
| tests/CONTRACT.md | Full spec-compliance test suite |
| claude.md | Language specification |
Festina intentionally favors:
Festina is not a scripting language with a compiler bolted on — it's a compiled, statically typed language designed from the start for native performance, that happens to keep its syntax approachable.