Skip to content
volt
GitHub

Why Volt

Volt is for code where you want C’s control and speed, and none of C’s guessing: what a line does is what it looks like it does, the compiler catches what it can, and debug builds catch the rest.

C’s speed, with nothing running behind you. There’s no garbage collector, scheduler, exception unwinder or vtable. Every method and trait call is resolved when compiling, and every allocation is one you wrote. On the benchmarks Volt matches or beats clang-compiled C on most programs, and wins by most where std does more than libc: sort sorts integers by radix (a tenth of C’s time with qsort), and the allocator takes small blocks from free lists (binary_trees).

Mistakes stop, loudly. Debug builds check what C leaves undefined: integer overflow, out-of-bounds indexing, null unwraps and double frees stop the program and name the line. --release drops the overflow and double-free checks and keeps the rest as a bare trap. The compiler rejects use after move, a match that misses a case and a format string that doesn’t fit its arguments. See Safety checks.

Ownership without a fight. Every value has one owner and is deleted when that owner’s scope ends. Moves are tracked and copies are explicit, so resources clean up like C++’s RAII, without lifetimes to annotate.

Errors you can see. A function that can fail returns E!T, and the caller has to try, catch or check it to get the value. Optionals (T?) mark what may be missing. Nothing is thrown.

Generic code that costs nothing. Templates make one copy per set of arguments, with specialization, packs and constant parameters. Code can run in the compiler (comptime), and types are values there.

Every other language is one step away. Volt reads C headers and C++ headers and modules (classes, templates, the standard library) directly, and imports ordinary Rust crates and Zig, Swift, Kotlin, Go, Java, C#, Python, TypeScript and JavaScript code the same way (use { "geom.rs" } as geom;, like a header); Lua it embeds through a package. The other way round, voltc bindings (or a bindings list in bolt.toml) makes a Volt library usable from C, C++, Rust, Zig, Python, JavaScript and TypeScript, C#, Java, Go, Lua, Dart, Swift, Kotlin and Ruby, and libvoltvm runs Volt source inside another program, as Lua is embedded. See Interop.

One toolchain. bolt builds packages and workspaces, fetches git dependencies, runs tests and benches, and runs build files written in Volt. Diagnostics show the code they’re about and suggest fixes; a language server and a VS Code extension come with it.

It compiles to C. The C backend writes readable C, so Volt runs wherever a C compiler does. The LLVM backend makes native code directly, for bare metal microcontrollers too, with no C compiler or C library at all. The compiler is written in Volt and builds itself through both.

Memory Errors Generics C interop Runtime
Volt owned, freed at scope end E!T templates, comptime reads C, C++ headers none
C manual return codes macros native none
C++ RAII exceptions templates native exceptions, RTTI
Rust borrow checked Result traits bindgen unwinding
Zig manual, allocators error unions comptime @cImport none
Go garbage collected extra returns generics cgo GC, scheduler

Volt sits between C++ and Zig: C++’s RAII and templates without exceptions, RTTI or implicit copies, and Zig’s error values and comptime.

  • You need proven memory safety. Volt tracks ownership and moves but has no borrow checker, so a reference can outlive what it points to. The compiler warns about common cases (a view kept across a change to its container, a reference to a local returned) and debug builds poison freed memory, which catches some of that, not all. Rust proves it at compile time.
  • You need a large package ecosystem. bolt has path and git dependencies, but no registry.
  • You need a stable language today. Volt is young: the language, std and tools still change, and there’s no 1.0 yet.