Skip to content

Releases: srdjan/zigttp

v0.16.0-rc8

22 Apr 15:05
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

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

22 Apr 12:34
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

v0.16.0-rc3 Pre-release
Pre-release

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

07 Apr 01:48

Choose a tag to compare

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

06 Apr 13:28

Choose a tag to compare

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

04 Apr 13:07

Choose a tag to compare

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 types
  • packages/zigttp-ext-demo/ - working demo extension (zigttp-ext:math)
  • zts/module_binding_adapter.zig - zero-copy comptime adapter from SDK to internal types
  • build.zig.zon with minimum_zig_version pinned to 0.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

  • VirtualModule enum removed from zts/modules/resolver.zig. Code using VirtualModule.fromSpecifier() or iterating std.meta.fields(VirtualModule) must switch to builtin_modules.fromSpecifier() and builtin_modules.all.
  • ResolveResult.virtual now holds *const ModuleBinding instead of VirtualModule.
  • Registration functions (registerVirtualModule, etc.) take comptime binding: ModuleBinding instead of VirtualModule.

Other Changes

  • self_managed_io flag on ModuleBinding replaces stringly-typed durable exclusion
  • SDK JSValue API tightened: NaN-boxing constants made private, null_val/exception_val removed
  • Comptime assertions for enum ordinal alignment between SDK and internal types
  • Extension adapter uses zero-copy @ptrCast for 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...v0.13.0

v0.12.0 - Compile-Time Verification & Contract Manifests

16 Mar 21:15

Choose a tag to compare

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 else branches, switch without default)
  • Result safety - Result values from jwtVerify, validateJson, etc. must have .ok checked before .value is 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": false when 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; mkdir uses absolute path for Zig 0.16 sandbox compatibility
  • Memory safety - errdefer guards on all dupe-before-append paths in contract builder; proper cleanup on error in ContractBuilder.deinit()
  • JSON fix - \u escape in contract serializer now correctly emits hex instead of decimal
  • Code dedup - findHandlerFunction shared between precompile tool and verifier; three extract functions unified into extractLiteralArg

Build Commands

# Verify + contract + AOT + optimized (the full pipeline)
zig build -Doptimize=ReleaseFast -Dhandler=handler.ts -Dverify -Dcontract -Daot

Documentation

  • Verification specification
  • README updated with Compile-Time Toolchain section
  • User Guide updated with verification and contract sections

v0.11.0 - Enhanced Error Detection

31 Jan 16:05

Choose a tag to compare

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 class and abstract class detection 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

31 Jan 13:16

Choose a tag to compare

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

📐 Architecture Guide

  • 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

Performance Guide

  • Benchmarks (QuickJS and Deno baselines)
  • Property access and string optimizations
  • Pool and request optimizations
  • Handler optimization tips
  • Deployment patterns

🔧 API Reference

  • 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

30 Jan 22:25

Choose a tag to compare

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 writeJson and HiddenClassPool methods, preventing UB in optimized builds
  • Restore array mutating methods - push, pop, shift, unshift, and splice now work correctly as builtin functions on Array.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 uses cpu * 2 (min 8) instead of cpu * 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...v0.9.0

v0.8.2 - Native Template Interpolation

27 Jan 17:58

Choose a tag to compare

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:

  1. Extracting world from the URL
  2. Concatenating: prefix + world + suffix
  3. 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.

Full Changelog

v0.8.1...v0.8.2