VonkRead the docs ↗

Vonk support

Build, understand
and operate Vonk.

A practical reference for the language, native web applications, Let's Encrypt and production operations.

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!");
}
ConstructPurpose and contract
int, float, bool, string, bytesBuilt-in scalar and binary values with checked operations.
recordStatically 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, continueStructured, 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");
}
HelperResponse
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

BoundaryCurrent contract
JSONStrict UTF-8 grammar, 64 KiB documents, depth 32, escaping and typed top-level fields.
PostgreSQLLoopback trust connection, literal SQL, bound text parameters and explicit transactions.
WorkspaceAffine root authority, bounded binary I/O, traversal and symlink rejection, atomic replacement.
Environment/configLiteral 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

SymptomLikely cause and action
Build output path missingCreate build/ and run from the repository root.
Cannot safely read TLS certificate or keyCheck path, owner, mode and private-key match.
ACME directory request failedCheck verbose log, ACME IPv4, outbound 443, system clock and trusted root.
ACME stops at HTTP-01Check public DNS, cloud and host firewall, port 80 and its owning process.
Invalid request framing after upgradeAn old app process is likely still running; verify PID and restart app and edge.
HTTPS has an empty responseTest 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.