zigttp

What if your agent
couldn't ship broken code?

zigts strips TypeScript down to the parts the compiler can prove, so zigttp can rewrite, re-prove, and ship only correct handlers. One binary. No runtime surprises.

zigts compiler-agent
$ zigttp expert "add /health and ship it"

[compiler-agent] Planning handler patch...
[compiler-agent] Simulating edit against zigts rules...
[compiler-agent] Re-running proofs + contract extraction...

PROVEN 7/7 proofs
CONTRACT stable: no new secrets, hosts, or modules
DEPLOY ready: health-check (1.2MB)

The Loop

zigts gives the compiler-agent something it can prove.

zigttp expert works because zigts cuts away the dynamic parts the compiler cannot sign. The compiler proposes the edit, checks it against the subset, reruns all 7 proofs, and stops at code it can certify.

The thing writing the patch is the thing rejecting unsupported moves. No shell agent guessing around a separate compiler.

zigttp expert
$ zigttp expert "add a health check endpoint with auth bypass"

[compiler-agent] Planning handler patch...
[compiler-agent] Simulating edit against zigts rules...

  error[E0017]: `try/catch` is not supported in zigts
    --> handler.ts:9:5
    = help: use assert() for Result narrowing

[compiler-agent] Rewriting with assert + match...
[compiler-agent] Re-running proofs + contract extraction...

  PROVEN 7/7 proofs
  CONTRACT stable: no new secrets, hosts, or modules
  Handler ready: health-check (1.2MB)

[compiler-agent] Created src/health-check.ts
[compiler-agent] Running zigts gen-tests health-check.ts...
[compiler-agent] Wrote 6 test cases to tests.jsonl (exhaustive paths)

What Ships

One binary. Five moving parts.

zigts makes handlers analyzable; the compiler-agent, proof engine, runtime, modules, and deploy pipeline build on that constraint.

01

Runtime and Performance

Pure-Zig execution for HTTP handlers, tuned for fast cold starts and tight memory.

pure Zig runtime x86-64 + ARM64 JIT zero-copy responses

02

Language and Type System

zigts trims TypeScript to an analyzable core, then adds match, guard, and comptime where proof needs them.

native TS + TSX distinct types + generics no async footguns

03

Compile-Time Analysis and Proofs

Seven static checks prove handler shape, narrow Results, and turn behavior into deployable contracts.

7-check verifier proof-driven cache capability-pinned sandbox

04

Virtual Modules and Native Capabilities

Capabilities live in native zigttp:* modules, so every import stays explicit and measurable.

20 native modules declared capabilities no npm polyfills

05

Deployment and Operations

Deploy consumes the proven contract, blocks unsafe diffs, and escalates only when capability surface changes.

zigttp deploy contract-aware review grants + drift

06

Durable and Concurrent Execution

Keep handler code linear, overlap I/O underneath, then opt into durable runs when the workflow must survive crashes.

parallel() + race() durable run keys timers + signals

07

Developer Experience and Agent Tooling

The compiler-agent edits inside the same proof system, while zigts gen-tests turns exhaustive paths into JSONL fixtures.

zigttp expert zigts gen-tests session replay

08

Extensibility and Embedding

Embed zigttp from Zig or add virtual modules without giving up explicit configuration.

zigttp-sdk native Zig embedding build-time tooling

The Provable Subset

TypeScript, cut down until it can be proved.

zigts removes the dynamic surface the compiler cannot sign. What stays is small enough to analyze and expressive enough to build real handlers.

import { method, pathname, params } from "zigttp:router";

const getUser = (id: string) =>
    fetchSync(`https://api.example.com/users/${id}`)
    |> Response.json;

function handler(req) {
    return match (`${method(req)} ${pathname(req)}`) {
        "GET /"          => Response.json({ status: "ok" }),
        "GET /health"    => Response.json({ healthy: true }),
        "GET /users/:id" => getUser(params(req).id),
        "POST /echo"     => Response.json(req.body),
        _                => Response.json(
                                { error: "Not Found" },
                                { status: 404 }
                            ),
    };
}

No npm

20 Zig modules. Zero npm surface.

Every capability ships as Zig. Imports stay explicit, sandboxes stay derivable, and npm stays out of the trust boundary.

Security

  • zigttp:authparseBearer, jwtVerify, jwtSign, verifyWebhookSignature, timingSafeEqual
  • zigttp:cryptosha256, hmacSha256, base64Encode, base64Decode

I/O and State

  • zigttp:ioparallel, race
  • zigttp:httpparseCookies, setCookie, negotiate, parseContentType, cors
  • zigttp:durablerun, step, stepWithTimeout, sleep, sleepUntil, waitSignal, signal
  • zigttp:cachecacheGet, cacheSet, cacheDelete, cacheIncr, cacheStats
  • zigttp:sqlsql, sqlOne, sqlMany, sqlExec
  • zigttp:serviceserviceCall

Data and Input

  • zigttp:envenv
  • zigttp:validateschemaCompile, validateJson, validateObject, coerceJson, schemaDrop
  • zigttp:decodedecodeJson, decodeForm, decodeQuery
  • zigttp:urlurlParse, urlSearchParams, urlEncode, urlDecode
  • zigttp:iduuid, ulid, nanoid

Flow and Utility

  • zigttp:routerrouterMatch
  • zigttp:composeguard
  • zigttp:scopescope, using, ensure
  • zigttp:loglogDebug, logInfo, logWarn, logError
  • zigttp:textescapeHtml, unescapeHtml, slugify, truncate, mask
  • zigttp:timeformatIso, formatHttp, parseIso, addSeconds
  • zigttp:ratelimitrateCheck, rateReset

Four Commands

First handler. First proof. Four commands.

Install. Init. Prove. Deploy.

workflow
# 1. Install from GitHub
$ curl -fsSL https://zigttp.timok.com/install | sh

# 2. Create a handler
$ zigttp init my-handler
  Created my-handler/handler.ts
  Created my-handler/tests.jsonl

# 3. Work with the compiler-agent
$ cd my-handler && zigttp expert "add auth + validation"
  PROVEN 7/7 proofs

# 4. Deploy
$ zigttp deploy
  Packaged OCI image
  Service provisioned

Core Commands

zigttp init
Bootstrap a new project
zigttp serve
Run a handler locally
zigttp dev
Watch mode with proof-aware reloads
zigttp expert
Compiler-native edit, proof, and repair loop
zigttp check
Verification and type checks
zigts gen-tests
Synthesize JSONL tests from exhaustive path enumeration
zigttp deploy
One-command build, push, and provision

Good Questions

The fast objections.

The questions that matter before you accept a restricted subset.

How is zigttp different from Node.js, Deno, and Bun?

Node.js, Deno, and Bun run the full language. zigttp uses zigts, a restricted subset, so the compiler can prove handlers, derive least-privilege sandboxes, and replay runs deterministically. That guarantee needs a closed language surface.

What does "proves your code correct" actually mean?

zigttp runs seven compile-time checks across every path: returns, reachability, Result narrowing, match coverage, property access, dead code, and contract extraction. Those proofs classify the handler and feed runtime policy, sandboxing, and deploy.

Can I use npm packages with zigttp?

No. zigttp ships 20 native zigttp:* modules in Zig, and the compiler tracks every import. If a module does not cover it, call the external API with fetchSync.

How do I install zigttp?

Use the README installer or download v0.16.0-RC8 from GitHub Releases. Building from source currently requires Zig 0.16.0.

Is it free and open source?

Yes. zigttp is MIT licensed on GitHub, including the runtime, compiler, and virtual-module standard library.