Releases: srdjan/zigttp
v0.16.0-rc8
Install
curl -fsSL https://raw.githubusercontent.com/srdjan/zigttp/main/install.sh | sh
Or download a tarball below and extract it manually.
Full Changelog: v0.16.0-rc3...v0.16.0-rc8
v0.16.0-rc3
Highlights since rc2
- zigttp:websocket - full RFC 6455 WebSocket support: handshake, frame I/O, onOpen/onMessage/onClose dispatch, getWebSockets broadcast, in-memory attachments, durable persistence, and setAutoResponse
- zigttp:fetch - web-standard outbound
fetch(url, init?)with durable replay under--durable - zigttp:scope - request-scoped lifecycle management module
- Coding agent (pi) - closed-loop agent loop, session persistence, /resume, REPL and TUI modes, --print/--mode json, Anthropic HTTPS backend, approval policy, and project-context injection
- Sandbox hardening - arena audit, persistent-string escape detection, security event stream (phases 1-5)
- Module governance - build-time capability audit, verify-modules governance mode, module-spec artifacts
- Proven live reload - contract-aware hot swap with --prove/--force-swap
- Deploy - zigttp login, region/wait flags, session refresh, content-addressed OCI refs
- Monorepo refactor - packages/runtime, packages/zigts, packages/tools, packages/modules as independent Zig packages
Install
curl -fsSL https://raw.githubusercontent.com/srdjan/zigttp/main/install.sh | sh
Or download a tarball below and extract it manually.
Full Changelog: v0.16.0-rc2...v0.16.0-rc3
v0.16.0-rc2
Install
curl -fsSL https://raw.githubusercontent.com/srdjan/zigttp/main/install.sh | sh
Or download a tarball below and extract it manually.
Full Changelog: v0.16.0-rc1...v0.16.0-rc2
v0.16.0-rc1
Install
curl -fsSL https://raw.githubusercontent.com/srdjan/zigttp/main/install.sh | sh
Or download a tarball below and extract it manually.
Full Changelog: v0.13.0...v0.16.0-rc1
v0.13.0 - Extension Modules, Contract Linking, Zig 0.16 Validation
Highlights
Packaged Extension Modules (zigttp-sdk)
Third-party virtual modules are now first-class. Extension authors depend on zigttp-sdk (a standalone Zig package) and declare a ModuleBinding with the zigttp-ext: prefix. Extensions get the full compile-time pipeline for free: contract extraction, type checking, flow analysis, trace/replay, and runtime sandboxing.
packages/zigttp-sdk/- SDK package with JSValue, ModuleFn, and all declarative typespackages/zigttp-ext-demo/- working demo extension (zigttp-ext:math)zts/module_binding_adapter.zig- zero-copy comptime adapter from SDK to internal typesbuild.zig.zonwithminimum_zig_versionpinned to0.16.0-dev.3073+28ae5d415
The VirtualModule enum is eliminated. All modules (built-in and extension) go through the unified ModuleBinding registry.
Cross-Handler Contract Linking
zts link system.json proves that a system of handlers communicates correctly at compile time. The linker resolves fetchSync URLs to target handler routes, checks response coverage, analyzes cross-boundary data flow, and detects failure cascades.
Zig 0.16.0-dev.3073 Validation
Pinned and validated against nightly 0.16.0-dev.3073+28ae5d415. Evented I/O networking still unimplemented upstream. Added nightly revalidation workflow to README.
zigttp:decode Module
Typed request ingress via import { decode } from "zigttp:decode". Schema-validated request parsing at the virtual module boundary.
Breaking Changes
VirtualModuleenum removed fromzts/modules/resolver.zig. Code usingVirtualModule.fromSpecifier()or iteratingstd.meta.fields(VirtualModule)must switch tobuiltin_modules.fromSpecifier()andbuiltin_modules.all.ResolveResult.virtualnow holds*const ModuleBindinginstead ofVirtualModule.- Registration functions (
registerVirtualModule, etc.) takecomptime binding: ModuleBindinginstead ofVirtualModule.
Other Changes
self_managed_ioflag onModuleBindingreplaces stringly-typed durable exclusion- SDK JSValue API tightened: NaN-boxing constants made private,
null_val/exception_valremoved - Comptime assertions for enum ordinal alignment between SDK and internal types
- Extension adapter uses zero-copy
@ptrCastfor args instead of per-element conversion - HandlerPool stress test stable on dev.3073 (5/5 runs)
- Long-header streaming test gated behind
ZTS_RUN_FLAKY_NIGHTLY_TESTS=1 - CLAUDE.md trimmed from 355 to 99 lines
Full Changelog
v0.12.0 - Compile-Time Verification & Contract Manifests
Compile-Time Verification & Contract Manifests
This release adds two new compile-time analysis passes that turn zigttp from "a fast small JS runtime" into "a runtime that understands what your handler is allowed to do."
Handler Verification (-Dverify)
Statically proves handler correctness at build time:
- Exhaustive returns - every code path returns a Response (missing
elsebranches,switchwithoutdefault) - Result safety - Result values from
jwtVerify,validateJson, etc. must have.okchecked before.valueis accessed - Unreachable code - statements after unconditional returns are flagged
This works because zigttp's JS subset eliminates all non-trivial control flow. The IR tree IS the control flow graph. Verification is a recursive tree walk, not a fixpoint dataflow analysis.
$ zig build -Dhandler=handler.ts -Dverify
verify error: not all code paths return a Response
--> handler.ts:2:17
= help: ensure every branch (if/else, switch/default) ends with a return statement
Contract Manifest (-Dcontract)
Emits a machine-readable contract.json describing what your handler is allowed to do:
- Virtual module imports and which functions are used
- Literal env var names (
"dynamic": falsewhen all calls use string literals) - Outbound hosts extracted from
fetchSync()URL arguments - Cache namespace strings from
cacheGet/cacheSet/etc. - Verification results (when combined with
-Dverify)
{
"modules": ["zigttp:auth", "zigttp:cache"],
"functions": { "zigttp:auth": ["jwtVerify"], "zigttp:cache": ["cacheGet"] },
"env": { "literal": ["JWT_SECRET"], "dynamic": false },
"egress": { "hosts": ["api.example.com"], "dynamic": false },
"cache": { "namespaces": ["sessions"], "dynamic": false }
}Non-literal arguments honestly report "dynamic": true. No other JS runtime can do this because full JS is not statically analyzable.
Also in This Release
- fetchSync - native outbound HTTP bridge with
fetchSync(url, init?)returning response-shaped objects - Build fixes - transpiler output includes
dep_count/dep_bytecodes;mkdiruses absolute path for Zig 0.16 sandbox compatibility - Memory safety -
errdeferguards on all dupe-before-append paths in contract builder; proper cleanup on error inContractBuilder.deinit() - JSON fix -
\uescape in contract serializer now correctly emits hex instead of decimal - Code dedup -
findHandlerFunctionshared between precompile tool and verifier; three extract functions unified intoextractLiteralArg
Build Commands
# Verify + contract + AOT + optimized (the full pipeline)
zig build -Doptimize=ReleaseFast -Dhandler=handler.ts -Dverify -Dcontract -DaotDocumentation
- Verification specification
- README updated with Compile-Time Toolchain section
- User Guide updated with verification and contract sections
v0.11.0 - Enhanced Error Detection
Enhanced Error Detection and Developer Experience
This release consolidates the fail-fast validation system to provide consistent, helpful error messages across all file types.
🎯 Highlights
- Consolidated Feature Detection: Unified error detection eliminates duplicate checks between TypeScript stripper and parser
- Comprehensive Documentation: New FEATURE_DETECTION.md documents all 46+ detected features
- Enhanced Error Messages: All unsupported features now include helpful alternatives
- Robust Testing: 15 new parser tests ensure reliable error detection
💡 Developer Experience Improvements
Consistent Error Messages
- Both .ts and .js files now show identical, helpful error messages
- Example:
'class' is not supported; use plain objects and functions instead
Fail-Fast Validation
- All unsupported features caught at parse time
- Prevents invalid code from reaching bytecode generation
- Clear suggested alternatives for every error
Better Documentation
- Complete matrix of all detected features with suggestions
- Clear separation between TypeScript-specific and JavaScript features
- Architecture documentation in CLAUDE.md
🐛 Bug Fixes
- Fixed type feedback allocation corrupting register state
📊 Benchmarks
- Added HTTP benchmark comparison vs Deno to README
📝 What's Changed
Error Detection
- Moved
classandabstract classdetection from stripper to parser for consistency - Enhanced all TypeScript stripper error messages with helpful alternatives
- Added comprehensive parser tests for unsupported features
Documentation
- Created zts/FEATURE_DETECTION.md with complete feature matrix
- Updated CLAUDE.md with unsupported feature detection architecture
- Added example error messages to documentation
Testing
- 15 new parser tests covering class, loops, operators, and error handling
- Stripper tests updated to reflect new architecture
- Integration tests verifying consistent errors across file types
See the full documentation for the complete list of detected features and their alternatives.
v0.10.0: Documentation Refactoring
This release focuses on improving documentation organization and accessibility.
Key Changes
Succinct README (76% smaller)
- Focus on quick start and key features
- Clear path to detailed documentation
- Better first-time user experience
New Comprehensive Guides
- System design and two-layer architecture
- Runtime model and memory management
- Performance architecture details
- Deployment patterns
⚛️ JSX Guide
- Complete JSX/TSX reference
- Component patterns and examples
- Server-side rendering (SSR) examples
- TypeScript JSX support
- Benchmarks (QuickJS and Deno baselines)
- Property access and string optimizations
- Pool and request optimizations
- Handler optimization tips
- Deployment patterns
- Handler API reference
- Advanced server configuration
- Extending with native functions
- Build configuration
Documentation Structure
README.md - Quick start (132 lines, was 552)
docs/
├── user-guide.md - Complete handler API reference
├── architecture.md - System design and internals
├── jsx-guide.md - JSX/TSX complete reference
├── performance.md - Benchmarks and optimizations
└── api-reference.md - Advanced configuration
All technical details from the original README have been preserved and better organized across focused documentation files.
Full Changelog: v0.9.0...v0.10.0
v0.9.0 - HTTP Performance & ARM64 Optimization
HTTP Performance & ARM64 Optimization
This release delivers significant improvements across the HTTP pipeline, ARM64 JIT backend, and runtime correctness.
Bug Fixes
- Fix JSON serialization undefined behavior - Added bounds validation before double-slice patterns in
writeJsonandHiddenClassPoolmethods, preventing UB in optimized builds - Restore array mutating methods -
push,pop,shift,unshift, andsplicenow work correctly as builtin functions onArray.prototype - Fix substring arena allocation - Eliminated GPA mutex contention caused by substring operations escaping the arena allocator
Performance
- ARM64 register-allocated locals: 2 to 6 - Reduces stack spills for functions with more local variables on Apple Silicon and other ARM64 targets
- Optimized HTTP layer for higher throughput - Streamlined request/response pipeline for lower per-request overhead
- Native query parameter parsing - Query strings are now parsed at the native Zig layer, bypassing bytecode execution
- Numeric query parameter coercion - Numeric query values are parsed as integers at the native layer, avoiding JS type conversion
- Native _processRequest function - Benchmark endpoint uses a fully native request processing path
- Pool startup tuning -
defaultPoolSize()now usescpu * 2(min 8) instead ofcpu * 4, and prewarm count reduced from 4 to 2
Benchmarks
Updated Deno baseline comparison (Apple Silicon):
| Endpoint | zigttp RPS | Deno Baseline | Ratio |
|---|---|---|---|
| /api/health | 79,743 | 104,672 | 0.76x |
| /api/echo | 79,409 | 63,726 | 1.25x |
| /api/greet/world | 80,030 | 105,016 | 0.76x |
Tests
- Added JSON object serialization test
- Added 6 array method tests: push, pop, shift, unshift, splice
- Added Deno baseline benchmark script
Full Changelog
v0.8.2 - Native Template Interpolation
Native Template Interpolation for Prefix Patterns
This release enables prefix route handlers (like /api/greet/:name) to bypass bytecode execution entirely by interpolating URL parameters directly into response templates.
New Features
- Response.rawJson() - New builtin method that accepts pre-serialized JSON strings, bypassing object serialization overhead
- Template pattern detection - Handler analyzer recognizes
Response.rawJson('prefix' + var + 'suffix')patterns in prefix routes - Native parameter interpolation - Runtime builds templated responses by concatenating prefix + URL param + suffix without interpreter execution
How It Works
When the handler analyzer detects a prefix pattern with a template response:
if (url.indexOf('/api/greet/') === 0) {
const name = url.slice(11);
return Response.rawJson('{"greeting":"Hello, ' + name + '!"}');
}The pattern is extracted at compile time:
- URL prefix:
/api/greet/ - Template prefix:
{"greeting":"Hello, - Template suffix:
!"}
At runtime, incoming requests to /api/greet/world are handled natively by:
- Extracting
worldfrom the URL - Concatenating: prefix +
world+ suffix - Returning the response without bytecode execution
Performance Impact
This optimization eliminates bytecode interpretation for templated responses, reducing the handler execution from multiple VM operations to simple string concatenation.