01 / Quickstart
From checkout to native binary
The C11 bootstrap builds the compiler. Application builds then stay inside Vonk's frontend, verifier, machine-code encoders and ELF64 writer.
make doctor
make build
mkdir -p build
./bin/vonk check examples/hello.vonk
./bin/vonk build examples/hello.vonk --target linux/amd64 -o build/hello
./build/hello
The generated application has no language VM, libc, dynamic loader, assembler subprocess or external linker. Linux ELFs must run on Linux for their target architecture.
02 / Language reference
Read and structure Vonk code
A source file contains records, functions, routes and tests. const bindings are immutable; let permits explicit local rebinding.
record User { name: string, active: bool }
fn greeting(user: User) -> string {
if (!user.active) { return "Inactive"; }
return "Hello, " + user.name + "!";
}
test "active greeting" {
assert(greeting(User("Ada", true)) == "Hello, Ada!");
}
| Construct | Purpose and contract |
|---|
int, float, bool, string, bytes | Built-in scalar and binary values with checked operations. |
record | Statically typed immutable data; fields and constructor arity are compile-time checked. |
[T] | Homogeneous immutable lists with checked index, append, concat and slice. |
T? | Optional value: create with some/none, inspect with has, read with unwrap. |
T! | Recoverable result: create with ok/err, inspect explicitly or propagate with ?. |
if, while, break, continue | Structured, lexically scoped control flow with boolean conditions. |
Modules, tests and diagnostics
Local imports form a deterministic package graph. An executable contains either fn main() -> int or HTTP routes. Runtime failures include source locations.
./bin/vonk check app.vonk
./bin/vonk test app.vonk
./bin/vonk dump-ir app.vonk
03 / Web applications
Compile routes into the executable
route GET "/api/status" {
return json_response("{"ok":true}");
}
route POST "/api/echo" (body: bytes) {
return text("received " + str(len(body)) + " bytes");
}
| Helper | Response |
|---|
text(value) | HTTP 200 plain text. |
html(value) | HTTP 200 HTML emitted verbatim; use trusted content until contextual templates land. |
json_response(value) | HTTP 200 after strict bounded JSON validation. |
error(status, value) | Explicit 400–599 response. |
GET routes take no parameter. POST requires one bytes parameter and accepts binary bodies up to 1 MiB. Each request runs in an isolated child process.
./bin/vonk build app.vonk --target linux/amd64 --port 8080 -o build/app
./build/app
curl -X POST --data-binary @payload.bin http://127.0.0.1:8080/api/echo
04 / Data and I/O
Cross boundaries explicitly
| Boundary | Current contract |
|---|
| JSON | Strict UTF-8 grammar, 64 KiB documents, depth 32, escaping and typed top-level fields. |
| PostgreSQL | Loopback trust connection, literal SQL, bound text parameters and explicit transactions. |
| Workspace | Affine root authority, bounded binary I/O, traversal and symlink rejection, atomic replacement. |
| Environment/config | Literal bounded names and copied values. |
const parsed = bytes_to_string(body);
if (!has(parsed) || !json_valid(unwrap(parsed))) {
return error(400, "Invalid JSON\n");
}
const name = json_string(unwrap(parsed), "name");
Database and workspace handles are affine: they cannot be copied into records or escape ordinary application signatures.
05 / Let's Encrypt
Issue and renew a real certificate
examples/letsencrypt.vonk implements ACME v2 HTTP-01 in Vonk: account, order, challenge responder, CSR, finalize, chain validation and atomic certificate replacement.
1. DNS and network
- Point the domain A record to the host.
- Allow inbound TCP 80 during validation and outbound TCP 443.
- Stop any other process using port 80.
2. Generate distinct keys and install the root
openssl ecparam -name prime256v1 -genkey -noout -out account-key.pem
openssl ecparam -name prime256v1 -genkey -noout -out certificate-key.pem
chmod 600 account-key.pem certificate-key.pem
curl -fsS https://letsencrypt.org/certs/isrg-root-x2.pem -o isrg-root-x2.pem
Never reuse the account key as the certificate key and never commit private keys.
3. Build and authorize port 80
make build
mkdir -p build
./bin/vonk check examples/letsencrypt.vonk
./bin/vonk build examples/letsencrypt.vonk --target linux/amd64 -o build/letsencrypt
sudo setcap cap_net_bind_service=+ep build/letsencrypt
4. Resolve the endpoint and request
export VONK_ACME_DOMAIN=vonk.page
export VONK_ACME_IP="$(getent ahostsv4 acme-v02.api.letsencrypt.org | awk 'NR==1 {print $1}')"
./build/letsencrypt | tee letsencrypt.log
Verbose output shows every safe protocol milestone. Success ends with issued; a certificate outside its 30-day renewal window returns current.
5. Validate and activate
openssl x509 -in fullchain.pem -noout -subject -issuer -dates -ext subjectAltName
nohup ./bin/vonk-tls --cert fullchain.pem --key certificate-key.pem --listen-port 443 --upstream-port 8080 >vonk-tls.log 2>&1 < /dev/null &
echo $! >vonk-tls.pid
After renewal, validate the new file and restart only vonk-tls. Run the issuer daily with systemd or a scheduler; non-due runs are safe no-ops.
06 / Production operations
Keep the app native and TLS mature
sudo apt-get install build-essential pkg-config libssl-dev libcap2-bin
make clean && make build && make tls-proxy
mkdir -p build
./bin/vonk build examples/web.vonk --target linux/amd64 --port 8080 -o build/web
sudo setcap cap_net_bind_service=+ep bin/vonk-tls
Run the app unprivileged on loopback. The OpenSSL frontend owns public port 443 and forwards to 127.0.0.1:8080. Use the hardened systemd units in docs/DEPLOYMENT.md.
ss -ltn | grep -E ':(443|8080)\b'
curl -fsS https://vonk.page/api/health
curl -X POST --data-binary 'hello' https://vonk.page/api/echo
tail -f web.log vonk-tls.log
After make clean, apply setcap again. Rebuilding an app does not replace its running process: restart it explicitly.
07 / Troubleshooting
Diagnose the failed boundary
| Symptom | Likely cause and action |
|---|
| Build output path missing | Create build/ and run from the repository root. |
| Cannot safely read TLS certificate or key | Check path, owner, mode and private-key match. |
| ACME directory request failed | Check verbose log, ACME IPv4, outbound 443, system clock and trusted root. |
| ACME stops at HTTP-01 | Check public DNS, cloud and host firewall, port 80 and its owning process. |
| Invalid request framing after upgrade | An old app process is likely still running; verify PID and restart app and edge. |
| HTTPS has an empty response | Test loopback first, then inspect both application and TLS logs. |
ps -p "$(cat web.pid)" -o pid,lstart,etime,cmd
ps -p "$(cat vonk-tls.pid)" -o pid,lstart,etime,cmd
curl -v http://127.0.0.1:8080/api/health
curl -v https://vonk.page/api/health
08 / Current limits
Know what is not implemented
Vonk is experimental. Contextual templates, authentication, sessions, remote PostgreSQL TLS/SCRAM, pooling, async tasks, WebSockets, HTTP/2 and a complete self-hosted compiler remain roadmap work. Multipart uploads, chunked request bodies and persistent HTTP connections are also absent.
The normative references are docs/STATUS.md, docs/SECURITY.md, docs/LANGUAGE.md, docs/DEPLOYMENT.md and dated verification reports.