C++ gives you control over memory and performance but punishes you with use-after-free bugs, buffer overflows, and undefined behavior. Rust fixes safety but has a steep learning curve. Jakt is a new systems language that's memory-safe like Rust but feels like TypeScript — and transpiles to C++ so you can use existing C++ libraries directly.
What Jakt Actually Does
Jakt is a systems programming language created by Andreas Kling (the creator of SerenityOS and the Ladybird web browser). It's designed to be the language you'd build if you loved C++ but wanted memory safety and modern ergonomics.
Jakt transpiles to C++ rather than compiling to machine code directly. This means you get memory safety guarantees at the Jakt level while leveraging the entire C++ ecosystem — existing libraries, toolchains, and optimizers. The generated C++ uses reference counting and bounds checking.
The syntax borrows from TypeScript and Rust: let bindings, pattern matching, generics, traits, and sum types (enums with data). But no lifetime annotations, no borrow checker — Jakt uses reference counting instead.
Open-source, part of the Ladybird browser project.
Quick Start
# Build Jakt compiler
git clone https://github.com/SerenityOS/jakt.git
cd jakt
cmake -B build && cmake --build build
Hello world:
fn main() {
println("Hello from Jakt!")
}
Compile and run:
./build/bin/jakt hello.jakt && ./build/hello
Jakt basics — feels familiar:
fn fibonacci(n: i64) -> i64 {
if n <= 1 {
return n
}
return fibonacci(n - 1) + fibonacci(n - 2)
}
fn main() {
for i in 0..10 {
println("{}", fibonacci(i))
}
}
3 Practical Use Cases
1. Safe Enums with Data (Sum Types)
enum Shape {
Circle(radius: f64)
Rectangle(width: f64, height: f64)
Triangle(base: f64, height: f64)
}
fn area(shape: Shape) -> f64 {
return match shape {
Circle(radius) => 3.14159 * radius * radius
Rectangle(width, height) => width * height
Triangle(base, height) => 0.5 * base * height
}
}
fn main() {
let shapes = [
Shape::Circle(radius: 5.0),
Shape::Rectangle(width: 4.0, height: 6.0),
Shape::Triangle(base: 3.0, height: 8.0),
]
for shape in shapes {
println("Area: {}", area(shape))
}
}
Exhaustive pattern matching — the compiler ensures you handle every variant.
2. Error Handling with Try
fn parse_config(path: String) throws -> Config {
let content = try read_file(path)
let parsed = try parse_json(content)
return Config(
host: parsed["host"] as! String,
port: parsed["port"] as! i64
)
}
fn main() {
let config = parse_config("config.json") catch error {
eprintln("Failed to load config: {}", error)
return
}
println("Server: {}:{}", config.host, config.port)
}
3. Classes with Safety
class HttpClient {
base_url: String
timeout_ms: i64
fn get(this, path: String) throws -> Response {
let url = format("{}{}", .base_url, path)
return try fetch(url, timeout: .timeout_ms)
}
fn post(this, path: String, body: String) throws -> Response {
let url = format("{}{}", .base_url, path)
return try fetch_post(url, body, timeout: .timeout_ms)
}
}
Why This Matters
Jakt occupies a unique niche: C++ interop with memory safety and modern syntax. For teams with large C++ codebases who want to write new code safely without rewriting everything in Rust, Jakt is a pragmatic migration path. The transpilation to C++ means your existing build system, debugger, and profiler all work unchanged.
The fact that the Ladybird browser (a serious systems project) is being written in Jakt validates it as a real-world systems language, not just a toy.
Need custom data extraction or web scraping solutions? I build production-grade scrapers and data pipelines. Check out my Apify actors or email me at spinov001@gmail.com for custom projects.
Follow me for more free API discoveries every week!
Top comments (0)