Ultra-lightweight, zero-dependency development HTTP server written in Zig
ezserve (Easy Serve) is an ultra-compact, cross-platform HTTP server built exclusively with Zig's standard library.
# Instantly serve current directory with just one command
./ezserve-
๐ชถ Ultra-lightweight - Binary size 73KB (ReleaseSmall) or 98KB (ReleaseFast)
-
๐ Zero dependencies - Uses only Zig standard library
-
๐ Cross-platform - Supports macOS/Linux (Windows currently unsupported)
-
โก Blazing fast - Multi-threaded with queue-based architecture
-
๐ ๏ธ Developer-friendly - Development mode, auto-open browser, file watching
-
๐ Production-ready - Range requests, ETag support, HTTP/1.1 compliance
# Build
zig build
# Start server (serves current directory)
./zig-out/bin/ezserve
# โ Server starts at http://127.0.0.1:8000
# Development mode with auto-open browser
./zig-out/bin/ezserve dev
# Specify port and root directory
./zig-out/bin/ezserve --port 8080 --root ./public
# High-performance production server
./zig-out/bin/ezserve --threads 16 --bind 0.0.0.0 --port 80
# Run tests
zig build test # Run all tests
zig build test-unit # Run unit tests only
zig build test-integration # Run integration tests only| Option | Description | Default |
|---|---|---|
--port <number> |
Specify port number | 8000 |
--root <path> |
Specify document root directory | . |
--bind <IP> |
Specify bind address | 127.0.0.1 |
--single-page |
SPA mode (return index.html on 404) | false |
--cors |
Add CORS headers | false |
--no-dirlist |
Disable directory listing | false |
--log=json |
Output access logs in JSON format (works in release builds) | false |
--threads <num> |
Number of worker threads (default: auto, max 8) | auto |
--watch |
Watch for file changes | false |
--open |
Auto-open browser after server start | false |
# Basic usage
./ezserve
# Development mode (CORS + auto-open + file watching)
./ezserve dev
# For SPA development (Vue.js, React, etc.)
./ezserve --single-page --cors --port 3000
# Development with custom settings
./ezserve dev --port 3000 --root ./src
# For LAN access
./ezserve --bind 0.0.0.0 --port 8080
# High-performance server with custom thread count
./ezserve --threads 16 --bind 0.0.0.0
# Minimal binary size for embedded/Docker
zig build -Doptimize=ReleaseSmall
./zig-out/bin/ezserve --root ./public # Only 73KB!
- CLI argument parsing
- Server startup and TCP connection handling
- HTTP request line parsing
- File serving (GET /path โ file response)
- SPA mode (return index.html on 404)
- CORS header support
- Automatic MIME type detection
- JSON access logging (basic implementation)
-
--bindoption (for LAN access) -
--no-dirlistoption (disable directory listing) -
--log=jsonoption (log format selection) - Default index.html serving for root path
- Port conflict handling - Graceful error when port is in use
- HEAD method support - For curl -I compatibility and CDN integration
- Buffer overflow protection - Handle large headers safely (upgraded to 8KB limit)
- MIME type optimization - Use HashMap for faster lookups
- Memory allocation optimization - Reduce allocator usage
- Better error messages - User-friendly error reporting
-
--helpoption (display usage) - Comprehensive test suite - Unit and integration tests
- Multi-threading support - Configurable worker threads with
--threads - Queue-based architecture - Eliminates socket errors and race conditions
- Binary size optimization - ReleaseSmall (73KB) vs ReleaseFast (98KB)
-
ezserve devcommand - Development mode with --watch + --open + --cors - File watching (
--watchoption) - Browser auto-open (
--openflag) - Better HTTP/1.1 compliance
- Range requests support (HTTP 206 Partial Content)
- ETag support (content-based cache validation)
- Gzip compression support
- Configuration file support (.ezserve.toml)
- IPv6 support
- HTTPS support (with development certificates)
- Plugin system
- WebSocket proxy
- Load balancing
ezserve supports structured JSON logging for production environments:
# Development: Standard logs only (debug builds)
./ezserve
# Output: 127.0.0.1 GET 200 1024 /index.html
# Production: JSON logs work in release builds
zig build -Doptimize=ReleaseFast
./zig-out/bin/ezserve --log=json
# Output: {"timestamp":1703123456,"method":"GET","path":"/","status":200,"content_length":1024,"client_ip":"127.0.0.1"}{
"timestamp": 1703123456,
"method": "GET",
"path": "/index.html",
"status": 200,
"content_length": 1024,
"client_ip": "192.168.1.100"
}Compatible with popular log aggregation tools:
- ELK Stack: Direct Elasticsearch ingestion
- Grafana Loki: Structured log queries
- Fluentd/Vector: JSON parsing ready
- CloudWatch/Datadog: Production monitoring
| Metric | ReleaseSmall | ReleaseFast |
|---|---|---|
| Binary size | 73KB | 98KB |
| Memory usage | ~600KB RSS | ~600KB RSS |
| Startup time | <50ms | <50ms |
| Throughput (10s test) | 1,626 req/s | 1,634 req/s |
| Peak performance | 3,255 req/s | 3,221 req/s |
| Read errors | <20 (0.1%) | <25 (0.15%) |
| Concurrent connections | Up to system limits | Up to system limits |
- Platform: macOS (Intel)
- Test tool: wrk (4 threads, 100 connections)
- Architecture: UltraPoller with queue-based multi-threading
| Tool | Binary Size | Dependencies | Startup Time | Features |
|---|---|---|---|---|
| ezserve | 73KB-98KB | Zero | <50ms | Zig-based, dev mode, multi-threading |
| Python http.server | ~50MB | Python | ~200ms | Built-in standard |
| Node.js http-server | ~30MB | Node.js | ~300ms | Via npm |
| Go net/http | ~10MB | Zero | ~100ms | Static binary |
| nginx | ~1MB | libc | ~100ms | Full web server |
# Development build (includes file watching and browser auto-open)
zig build
# Performance optimized build (98KB, max speed)
zig build -Doptimize=ReleaseFast
# Size optimized build (73KB, good speed)
zig build -Doptimize=ReleaseSmall
# Cross-compilation examples
zig build -Doptimize=ReleaseFast -Dtarget=x86_64-windows
zig build -Doptimize=ReleaseFast -Dtarget=x86_64-linux
zig build -Doptimize=ReleaseFast -Dtarget=aarch64-linuxThe project includes a comprehensive test suite with both unit and integration tests.
tests/
โโโ test_files/ # Test assets for integration tests
โ โโโ test.html # Sample HTML file
โโโ integration_tests.zig # HTTP endpoint tests
src/
โโโ lib.zig # Core library with embedded unit tests
โโโ main.zig # Application entry point
# Run all tests
zig build test
# Run only unit tests (fast)
zig build test-unit
# Run only integration tests (requires building executable)
zig build test-integration- Unit Tests: MIME type detection, configuration structures, response handling
- Integration Tests: HTTP GET/HEAD requests, error responses (404, 405), file serving
- Edge Cases: Unknown file extensions, malformed requests, port conflicts
Pull requests and issues are always welcome!
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a pull request
MIT License - see the LICENSE file for details.