The agent writes only what the compiler can prove.
zttp is an agent-compiler: a restricted TypeScript profile with bounded static analyses, a compiler-in-the-loop coding agent, and a local runtime. Describe the handler you want in plain English. The agent drafts it, and the compiler simulates every draft before it reaches disk. A draft that adds a violation is vetoed; supported repairs are normalized or applied before the edit can land. A deployed binary carries the resulting certificate, and an independent consumer checker decides which claims meet the runtime's policy before the handler can serve. The binary needs no npm or Node.
zttp init my-app --expert
# then: "add a GET /health route and a POST /echo that validates JSON"The agent proposes a compiler-verified edit and you approve only code that passes. When your intent is ambiguous, it asks one question instead of guessing.
Prefer to write the handler yourself? The same compiler runs the watch loop:
zttp dev # recompile and print a proof card on every save
zttp test
zttp deploy # self-contained binary, proof ledger entry, signed receiptPre-built binaries are published for macOS and Linux on x86_64 and aarch64:
curl -fsSL https://raw.githubusercontent.com/srdjan/zigttp/main/install.sh | shOr build from source with Zig 0.16.0:
git clone https://github.com/srdjan/zigttp.git
cd zigttp
zig build -Doptimize=ReleaseFaststructural Guardrails<T> = Proof<T,
| "deterministic"
| "no_secret_leakage"
| "injection_safe"
>;
function HomePage(): JSX.Element {
return (
<html>
<head><title>Hello</title></head>
<body><h1>Hello from zttp</h1></body>
</html>
);
}
function handler(req: Request): Guardrails<Response> {
if (req.path === "/") {
return Response.html(renderToString(<HomePage />));
}
if (req.path === "/api/echo") {
return Response.json({ method: req.method, path: req.path });
}
return Response.text("Not Found", { status: 404 });
}See examples/ for routing, JSX/TSX, SQL, fetch, durable workflows, and proof examples.
- Five core commands:
init,dev,test,expert,deploy. Advanced commands are listed byzttp help --all. - Handler API:
function handler(req): Response, plusResponse.text,Response.json, andResponse.html, andresource(data, affordances)for content-negotiated HAL-JSON and HTMX from one declaration. - Language profile: a restricted JS/TS/TSX subset with no
var,while,class, ortry/catch; unsupported constructs fail at compile time. - Proofs: response-path verification, Result/optional checks, state-isolation
checks, active
Proof<T, P>obligations, flow checks, proof traces, witnesses, proof receipts, and artifact-level proof certificates. Production startup reconstructs the required obligations and executable graph with an independent checker instead of trusting the compiler's serialized verdict. - Virtual modules: native modules under
zttp:*for env, crypto, auth, validation, cache, SQL, fetch, service calls, routing, durable and multi-handler workflows, structured I/O, logging, IDs, time, text, and more. - Local deploy: self-contained binary output under
.zttp/deploy/<project-name>with mandatory certificate acceptance and default-on provenance attestation.
Read the Threat Model before running untrusted code or exposing a binary publicly. Two boundaries are easy to miss:
devandservefrom source are not a sandbox. They run handler code with your user's permissions for fast iteration. The enforced surfaces are the precompiled (-Dhandler=) anddeploybinaries, which carry and enforce the contract-derived capability allowlist (egress, env, cache, SQL). Apolicyentry inzttp.jsonnarrows that allowlist at analysis time instead: every project-backed command checks the handler against it, and a policy that cannot be read is an error rather than an unrestricted verdict. See Contracts and Sandboxing.- A contract that matches the loaded bytes is still a set of compiler claims.
Deployed artifacts must also pass certificate acceptance before startup. Only
properties that clear the production policy can enable proof-authoritative
caching, pooling, check elision, or durable-workflow guarantees.
-Dhandlerbuilds enforce their capability policy but carry no certificate and receive no proof promotion. - No TLS. The runtime serves plain HTTP and binds
127.0.0.1by default. Terminate TLS at a reverse proxy and set the host explicitly before exposing a deployed binary to public traffic. expertdefaults to DeepSeek, so a turn sends handler source to a third party. The destination line under the banner states this before the first turn. Select--provider localto keep the source on the machine, throughLiquidAI/LFM2.5-2.6B-MLX-8biton a developer-managed loopback MLX-LM server. Zttp checks readiness but never manages the process or falls back to another provider. Attestation is on by default and publishes a stable per-user public-key fingerprint at/.well-known/zttp-attest.
Benchmark claims are kept in Performance. The measured
baseline is roughly a 3.5 ms cold-start floor, 7-15 ms typical cold start
depending on host load, about 13 MB RSS after first response, and about 112k
req/s on the documented HTTP benchmark. These numbers are pending receipt-backed
measurement in this repo; zig build bench covers the in-process benchmark
suite, while cold-start/RSS/HTTP-throughput evidence still comes from the
external/manual harness noted in the performance docs.
Start at the Documentation Index.
- User Guide - setup, handlers, routing, testing, deployment, proof receipts, and troubleshooting.
- CLI Reference - core commands and advanced machine tools.
- Virtual Modules - complete current module list and runtime requirements.
- Contracts and Sandboxing - contract
extraction, runtime policy, replay, OpenAPI, SDK emit, and
Proof<T, P>. - Verification, TypeScript, Sound Mode, and Restrictions to Proofs.
- Performance, Reliability, Roadmap, and Architecture.
- Cassette Recording - how to re-record the codegen corpus against DeepSeek (the default), a local MLX server, Claude, or OpenAI, and how to republish convergence and coverage after.
See CONTRIBUTING.md. Security reports go through SECURITY.md.
MIT.
