Releases: srdjan/zigttp
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.
Full Changelog
v0.8.1
Performance Release: 100K+ RPS
This release focuses on HTTP pipeline optimizations, achieving over 100K requests per second on the echo endpoint.
Benchmark Results
| Endpoint | zigttp | Deno (baseline) | Ratio |
|---|---|---|---|
| /api/health | 104,147 RPS | 104,672 RPS | 99.5% |
| /api/echo | 102,539 RPS | 63,699 RPS | 161% (+60.9%) |
| /api/greet/world | 67,183 RPS | 104,963 RPS | 64% |
What's New
Prebuilt Response Fast Path
- Complete HTTP responses serialized at compile time for static patterns
- Single syscall write bypasses all header construction
- Zero runtime string formatting for matched patterns
Reduced Syscalls
writev()scatter-gather I/O combines headers + body without copying- Increased buffers from 4KB to 8KB to fit more responses in single write
- Fast header slots (connection, content-length, content-type) populated during parsing
Pool Optimizations
- Thread-local cache increased from 1 to 2 slots
- Removed atomic counter from acquire/release hot path
- LIFO hotness tracking for better cache locality
JIT Improvements
- Consolidated pointer extraction with
emitExtractPtrhelper - Low-bit pointer tagging for JIT compatibility
v0.8.0
What's New
String Slices (Zero-Copy Substrings)
- New
MemTag.string_slicefor zero-copy substring operations JSStringSlicestruct references parent string with offset/length- Eliminates allocation for
substring(),slice(), and similar operations
Handler Pattern Analyzer
- Compile-time detection of static response patterns
- Builds fast dispatch table for URL routing
- Native fast path bypasses bytecode interpreter entirely
- Detects exact match (
url === '/api/health') and prefix match patterns
NaN-Boxing Improvements
- Inline float storage eliminates heap allocation for all f64 values
- Low-bit pointer tagging for JIT compatibility
- Full 48-bit address support on ARM64 Linux
JIT Enhancements
- Polymorphic inline caches (4 shapes vs 1 for monomorphic)
emitExtractPtrhelper consolidates pointer extraction- Multi-page code regions for larger JIT functions
- ARM64 float rounding instructions (floor/ceil/round/abs)
Rope Data Structure
- O(1) string concatenation via tree nodes
- Lazy flattening deferred until content access
- Eliminates O(n^2) string building overhead
AIR (Abstract Intermediate Representation)
- CFG-based SSA representation for optimized JIT tier
- Enables CSE, LICM, and guard hoisting optimizations
Performance
| Endpoint | Deno | zigttp | Improvement |
|---|---|---|---|
| /api/health | 25,178 RPS | 25,282 RPS | +0.4% |
| /api/echo | 19,984 RPS | 25,188 RPS | +26% |
| /api/greet/world | 24,907 RPS | 24,911 RPS | +0.01% |
Other Improvements
- Compiler optimizations: capacity pre-allocation, atom-based scope lookups
- Hot loop early JIT compilation (50 backedge threshold)
- Fast monomorphic call guards with guard_id
- PIC entry initialization prevents JIT false matches