Skip to content

Why Weld

Weld is a small, statically-typed web-service language that compiles to Zig — and, through Zig, to a native static binary for the architecture of your choice.

   hello.weld ──weld──▶ hello.zig ──zig build-exe──▶ native binary
  (your source)        (generated)   (-target …)      (x86_64 / aarch64 / riscv64 / …)

Weld is itself written in Zig, so the whole toolchain is one dependency: the Zig compiler.

Why compile to Zig?

Zig ships a batteries-included, LLVM-free cross-compiler. By emitting Zig, Weld inherits:

  • Cross-compilation for free-target aarch64-linux, riscv64-linux, … no extra toolchains.
  • Small, static binaries — the generated server links only std.
  • A stable C ABI and a real optimizer — without Weld having to own a backend.

What you get

A .weld file becomes a running, cross-compiled native HTTP server — with path parameters, wildcards, typed records, enums, sum types, generics, and response interpolation — plus a generated TypeScript/JS client for the frontend. WebSocket hubs with connect-time auth and request-id-correlated method calls run on the same port.

The integrations are written from scratch in pure Zig, depending only on std:

  • Native Postgres over the v3 wire protocol (no libpq), with prepared statements, connection pooling, SCRAM-SHA-256 auth, and transactions.
  • HTTP / HTTPS upstreams with a real TLS handshake and CA verification.
  • gRPC over a from-scratch HTTP/2 (h2c) + protobuf stack — unary and all three streaming modes.
  • WebSocket hubs implementing the RFC 6455 handshake and frame codec by hand.
  • JWT (HS256 verify/decode) and rate limiting written in Weld itself.

The example that started it

weld
route GET "/" {
    type "text/html"
    respond "<h1>Weld API</h1>\n"
}

# :id is a typed int; {id} interpolates it (a bad int → 400)
route GET "/users/:id" (id: int) {
    respond "user id = {id}\n"
}

# two typed params plus an optional query param, defaulted with ??
route GET "/users/:id/posts/:post" (id: int, post: int, query q: string?) {
    respond "user {id}, post {post}, filter={q ?? "none"}\n"
}

# trailing wildcard captures the rest of the path
route GET "/files/*path" {
    respond "serving file: {path}\n"
}
sh
$ curl localhost:8080/users/7/posts/99?q=recent
user 7, post 99, filter=recent
$ curl localhost:8080/files/docs/readme.md
serving file: docs/readme.md

Status

Working MVP: a .weld file becomes a running, cross-compiled native HTTP server plus a generated client. Not production-ready.

Next: Getting Started.