Bytecode VM + Cranelift JIT
- Portable .abc bytecode - magic header ARTHBC01.
- Tiered Cranelift JIT: Interpreter, Baseline at 100 calls, Optimized at 1,000.
- On-stack replacement swaps hot loops into compiled code mid-run.
Arth - the systems language
Arth gives you memory safety without the ceremony - no garbage collector, no lifetime annotations, no null. Familiar Java-style syntax, safety the compiler proves for you, and native binaries at the end.
String a = "hello";
int len = a.then(StringFns.length());
// an immutable borrow - a still owns it
println(a); // ok
borrow checked - no null, no GC, no lifetime to write

What Arth gives you
Every language asks you to give something up. Arth's bet is that you should not have to trade safety for a garbage collector, or safety for lifetimes. Here is what that buys you - one short line each, no jargon.
Memory
Rust-grade safety with every borrow region inferred - not a single lifetime annotation to write.
Runtime
Deterministic RAII: a value is destroyed the moment its owner leaves scope. No GC pauses.
Types
There is no null - absence is a type, Optional<T> - and checked exceptions are typed.
Concurrency
Async, actors and channels on a work-stealing executor. Data races are a compile error.
Stdlib
96 modules ship in the box - crypto, databases, mail, HTTP and more, all written in Arth.
Backends
A bytecode VM with a JIT and an LLVM native path, both calling the arth-rt native runtime.
Memory safety
EditorStandard library
RuntimeHow it compares
Every language asks you to give something up. A Rust alternative usually means paying in lifetimes and a steep syntax; a systems language without a garbage collector usually means C-shaped ergonomics. Arth vs Rust vs Go vs Java, on the axes that matter - and the neighbours keep their real strengths.
Arth is pre-1.0. Rust, Go and Java are proven production languages with huge ecosystems and tooling behind them. Arth's bet is narrower - Rust-grade safety with Java-like syntax and no lifetime annotations - and it trades maturity, ecosystem and scale for that, which we say plainly.
Under the hood
The story above is the plain version. For engineers, here is the machinery - the compiler is one Rust workspace that lexes, parses, resolves, type-checks and borrow-checks, then hands one IR to whichever backend you pick.
Ownership without lifetimes
The signature move: Rust-grade guarantees - moves, borrows, deterministic drops - but the compiler infers every borrow region. Where Rust makes you write the lifetime, Arth works it out.
Rust needs the annotation
fn first<'a>(xs: &'a Vec<String>)
-> &'a String {
&xs[0]
}
// the 'a lifetime is on you
Arth infers it
borrow String first(List<String> xs) {
return xs.get(0);
}
// no lifetime - an NLL-style region solver proves it
Caught at compile time
Use-after-move, mutating a final field, an uncaught typed exception, a stray null - in most languages these ship. In Arth they never compile. Real diagnostics, straight from the checker.
String b = a;
println(a);
final String appName;
cfg.appName = "NewApp";
Config c = parse(src);
// parse throws (ParseError)
Optional<User> u = repo.find(id);
// there is no null in Arth
Concurrency by message-passing
Send messages, do not share memory. Tasks run on a work-stealing executor and talk over MPMC channels; the same ownership rules make data races a compile error.
async producer
Task<void>
channel
MPMC buffer
async consumer
Task<void>
Channel<int> ch = Channel.create(10);
Sender<int> tx = ch.sender();
Receiver<int> rx = ch.receiver();
Task<void> producer = async {
await tx.send(i); // backpressure
};
Task<void> consumer = async {
Optional<int> v = await rx.recv();
};
Actors own their state and talk over channels; a bounded channel applies backpressure so a fast producer cannot outrun a slow consumer. No mutexes to forget, no lock ordering to get wrong.
Atomic<T> exposes compare-exchange and fetch-add with Relaxed, Acquire, Release, AcqRel and SeqCst orderings - the same tools you would reach for in Rust.
Two backends and a native runtime
One IR, two ways out: a portable bytecode VM with a tiered Cranelift JIT, or a native LLVM binary. Both call the arth-rt native runtime for the standard library.
source .arth
You write it
check + borrow
Resolve, type, borrow-check
IR (SSA/CFG)
One shared IR
codegen
VM or native LLVM
$ arth check src/
$ arth build --backend vm src/
$ arth build --backend llvm src/
$ arth run app.abc
// lex | parse | check | build | run | fmt | emit-llvm
The Cranelift AOT backend is still a stub - the JIT is the real, shipping path. LLVM builds for the host target only: there is no cross-compilation yet.
Editor support ships too: an arth-lsp server and a VSCode extension - syntax plus basic LSP today, richer semantics on the way.
155 conformance tests (VM + LLVM parity) - 460K+ fuzz runs - 12 / 12 native integration tests - 125+ concurrency e2e tests
Private - early access
Arth is in private access while it approaches 1.0 - no public download, no self-serve sign-up. Request an invite and we will get you into the workspace: one build to the compiler, one command to your first program. If you want memory safety without the ceremony, we would like to compare notes early.