Voxlang
Voxlang. Programs you can read aloud.

English sentences in.
Native assembly out.

Voxlang compiles a constrained, sentence-based English syntax straight to assembly. English sentences in, native assembly out, with no runtime, no libc, no garbage collector. Programs are tiny static binaries made of your code and system calls, nothing else.

To 'test the divisibility' with a number called n and a number called by.
  Return a boolean,
    n modulo by is 0.

print each number from 1 to 15,
  but if 'test the divisibility' of the number and 15 print "fizzbuzz",
  but if 'test the divisibility' of the number and 3 print "fizz",
  but if 'test the divisibility' of the number and 5 print "buzz".

Fizzbuzz in plain prose: one sentence tests divisibility and prints each number from 1 to 15.

; Generated by vox 0.4.15
; Target: x86_64 Linux (NASM)

%include "coreasm/x86_64/core.asm"
%include "coreasm/x86_64/io.asm"
%include "coreasm/x86_64/int.asm"
%include "coreasm/x86_64/funcs.asm"

section .data
    str_0: db 'fizzbuzz', 0
    str_0_len: equ $ - str_0 - 1
    str_1: db 'fizz', 0
    str_1_len: equ $ - str_1 - 1
    str_2: db 'buzz', 0
    str_2_len: equ $ - str_2 - 1

section .text
global _start

_start:
    push rbp
    mov rbp, rsp
    sub rsp, 16

    mov rax, 1
    mov [rbp-8], rax
    mov rax, 15
    inc rax
    mov [rbp-16], rax
.for_start_0:
    mov rax, [rbp-8]
    cmp rax, [rbp-16]
    jge .for_end_2
    mov rax, 15
    push rax
    mov rax, [rbp-8]
    push rax
    pop rdi
    pop rsi
    call test_the_divisibility
    test rax, rax
    jz .else_4
    PRINT_STR str_0, str_0_len
    PRINT_NEWLINE
    jmp .if_end_3
.else_4:
    mov rax, 3
    push rax
    mov rax, [rbp-8]
    push rax
    pop rdi
    pop rsi
    call test_the_divisibility
    test rax, rax
    jz .else_6
    PRINT_STR str_1, str_1_len
    PRINT_NEWLINE
    jmp .if_end_5
.else_6:
    mov rax, 5
    push rax
    mov rax, [rbp-8]
    push rax
    pop rdi
    pop rsi
    call test_the_divisibility
    test rax, rax
    jz .else_8
    PRINT_STR str_2, str_2_len
    PRINT_NEWLINE
    jmp .if_end_7
.else_8:
    mov rax, [rbp-8]
    mov rdi, rax
    PRINT_INT rdi
    PRINT_NEWLINE
.if_end_7:
.if_end_5:
.if_end_3:
.for_continue_1:
    inc qword [rbp-8]
    jmp .for_start_0
.for_end_2:

    ; Exit program
    EXIT 0

; User-defined functions
; Function: test the divisibility
test_the_divisibility:
    FUNC_PROLOGUE 16
    push rdi  ; save arg word
    push rsi  ; save arg word
    call _check_call_depth
    pop rsi  ; restore arg word
    pop rdi  ; restore arg word
    mov rax, rdi
    mov [rbp-8], rax  ; param payload
    mov rax, rsi
    mov [rbp-16], rax  ; param payload
    mov rax, 0
    push rax
    CLEAR_LAST_ERROR  ; clear error before arithmetic
    mov rax, [rbp-16]
    push rax
    mov rax, [rbp-8]
    pop rbx
    INT_MOD
    pop rbx
    INT_EQ
    push rax  ; save return value
    call _dec_call_depth
    pop rax  ; restore return value
    FUNC_EPILOGUE

115 lines of NASM from 8 lines of Vox; a 4,552-byte static binary, stripped.

Why

Voxlang closes the gap between what a developer says a program does and what is actually written there, so review and audit start from the same sentence.

  • The description and the program are the same artefact.

    Two developers sit at one screen.

    Read more

    One is walking the other through a function he just wrote, pointing at the code with his finger as he goes. He does not read every symbol. He summarises: this checks whether the number divides evenly, then loops from one to fifteen and prints fizzbuzz on the right multiples. He is describing the program, not reading it, because the text on the screen and the sentence in his mouth are two different things.

    That gap, between what a person says a program does and what is actually written there, is the whole problem code review lives inside. Humans do not speak in brackets and semicolons. We speak, and think, in sentences.

    Here is the turn: in Voxlang, the sentence he would say out loud is what the program already looks like. There is no translation step, because the description and the program are the same artefact.

    Two consequences follow, stated plainly. Anyone can read a Voxlang program and follow what it does, including someone who has never written a line of any language, so review stops being gatekept by who knows the syntax. And in 2026, more and more code is written by models, and somebody accountable still has to sign it off. A source that skim-reads like prose lets that person read a whole program the way they read a novel: follow what it does, and notice the paragraph that does not belong. Voxlang makes machine-written code auditable by the human who answers for it.

    Clear reading is not the same as correct logic, so Voxlang aims to give you both halves of the check: every sentence compiling to exactly what the manual says it means, and a program that reads plainly enough for a person to tell whether that is what was meant.

    Said

    To check whether one number divides another evenly, see if the remainder is zero. Then, for every number from one to fifteen, print it. But if it divides evenly by six, print fizzbuzz. If it divides evenly by two, print fizz. If it divides evenly by three, print buzz.

    Written
    To 'check divisibility' with a number called x and a number called y.
      Return a boolean,
        x modulo y is 0.
        
    For each number from 1 to 15,
      print the number,
        but if 'check divisibility' of the number and 6 is true print "fizzbuzz",
        but if 'check divisibility' of the number and 2 is true print "fizz",
        but if 'check divisibility' of the number and 3 is true print "buzz".
  • Memory, without a garbage collector.

    Voxlang makes a promise about memory too, and keeps it without a garbage collector, without a runtime, and without tracing anything while the program runs.

    Read more

    The guarantees come from compile-time structure and from small inline checks the compiler writes directly into the generated assembly.

    A Voxlang program never touches a raw pointer directly. The compiler allows one explicit escape hatch, casting a buffer, text or list as a number, which hands back the pointer value itself for the program to use as an ordinary number. Outside that cast, every access to memory goes through a buffer the compiler manages: it owns the allocation, tracks the size, and knows the lifetime. A dynamic buffer grows as you append to it, its size tracked explicitly. A fixed buffer does not grow: a write past its declared capacity is refused rather than reallocated, so a bound you wrote down stays a bound.

    An out-of-bounds access is not a crash. It becomes a no-op, an error flag is set, and execution continues, so the program can check that flag and handle it itself, with no traps, no exceptions, no runtime handler catching anything on its behalf. Buffers, file descriptors, and other resources are tracked the same way, and released deterministically on exit even when the cleanup was never written by hand.

    None of this is Rust wearing a different syntax, and the project says so itself. As the compiler's own README puts it: "While Vox does not replicate Rust's type system, it aims for a similar practical outcome: predictable, memory-safe programs without a garbage collector or runtime system." It is its own method, judged by its own results, not a claim to be something else.

    Source: README.md, Memory Safety Model

  • For advanced users

    Small binaries, nothing in the way, assembly you can read.

    Voxlang compiles straight to assembly with no runtime system and no standard library, so its binaries are small by construction, well suited to static utilities and constrained environments.

    Read more

    Built today with vox 0.4.15: the compiler's own hello.vox compiles to a static 4,552-byte executable (stripped), and the clock example on this page compiles to 4,552 bytes (stripped). Neither links libc. As of the next release, the Vox compiler has no dependencies beyond the Rust standard library, and the programs it builds have none at all: no libc, no runtime.

    That smallness is honest about what it buys. There is no interpreter to start and no garbage collector to pause the program mid-run: the binary is the program, making the system calls it makes and nothing else. Voxlang does not claim to be faster than C; matching C's performance on numeric benchmarks is a stated goal, not a result yet.

    What the compiler emits is plain NASM, readable the same way the source is. The runtime it depends on is a directory of assembly macros, coreasm: on the Fedora Copr package it sits as a plain directory beside the compiler binary, and from cargo install it is embedded in the binary itself and unpacked to a cache directory the first time it runs. Either way it ends up as real files on disk, yours to read, and on your own copy, to change.

Introduce your AI to Vox
Read the full Voxlang reference at https://vox-lang.dev/llms-full.txt and follow its installation instructions for my system; the latest release is 0.4.15. Follow the language spec and style guide.

Copies a setup prompt for your coding agent.

Install

cargo
cargo install vox-lang
Fedora Copr
sudo dnf copr enable vox-lang/Vox
sudo dnf install vox
Nix
nix run github:Vox-lang/vox
nix profile install github:Vox-lang/vox

“Vox also ships as a flake in this repo, so it works straight from the GitHub URL with no separate registry.”

From source
make build
sudo make install
Editor

VoxLang

Syntax highlighting for Voxlang's sentence-based .vox files, nothing more yet.

code --install-extension vox-lang.vox-lang

v0.4.2 · publisher vox-lang