Local reverse proxy with TLS termination, custom DNS, and a terminal UI for inspecting, intercepting, and replaying HTTP traffic. Launch and monitor your dev server in a split-pane alongside the request log.
$curl -fsSL https://raw.githubusercontent.com/vandot/zlodev/main/install.sh | sh
On Windows, download the binary from GitHub Releases and run in an elevated terminal.
TLS termination with auto-generated CA and domain certificates. Your browser sees a trusted green lock.
Route by subdomain (api.dev.lo) or path prefix (/api) to local ports or external hosts. Color-coded in the TUI.
Resolves *.lo to localhost automatically. No /etc/hosts editing needed.
Live request list with method, path, status, timing, and body size. Detail view for headers and body. Optional split-pane logs for your dev server output.
Hold requests or responses matching a pattern. Inspect, edit status/headers/body, accept, or drop. Use req: or resp: prefix to target a specific phase.
Re-send any captured request. Edit method, path, headers, and body before replaying.
Export captured traffic as HTTP Archive files for sharing, analysis, or import into other tools.
Copy any request as a ready-to-run curl command with a single keystroke.
Transparent proxying of WebSocket upgrades. HMR and live-reload just work.
Reads .env and framework configs to find your dev server port. Zero config for most setups.
Browsers and upstream services gate real functionality behind TLS. Without local HTTPS, you're testing a different app than what runs in production.
Stripe, GitHub, Twilio, and Slack all require HTTPS callback URLs. Without a local HTTPS endpoint you're deploying to staging just to test a handler, or re-registering ngrok URLs every session.
Most identity providers (Entra ID, Auth0, Okta, Google) reject redirect URIs that aren't HTTPS. A valid local cert lets you complete the full auth flow without dev-only exceptions that diverge from production.
Browsers treat Secure and SameSite=None cookies differently over plain HTTP. If your app relies on cross-site cookies, embedded iframes, or BFF patterns, you can't reproduce the real behavior without TLS.
Browsers block mixed HTTP/HTTPS content aggressively. Local HTTPS lets you catch broken asset references, hardcoded http:// URLs, and HSTS preload issues before they hit staging.
Service workers are gated behind secure contexts. No HTTPS means no registration outside localhost, which makes offline-first and progressive web app development painful.
Security headers like Content-Security-Policy and upgrade-insecure-requests behave differently in secure vs. insecure contexts. Testing locally with HTTPS matches production semantics.
Localhost exceptions don't apply when your phone hits your dev box over the local network. A valid cert on a real hostname avoids the certificate warning dead-end on iOS and Android.
If production traffic flows through Cloudflare, Azure Front Door, or an NGINX ingress with TLS termination, local HTTPS lets you test X-Forwarded-Proto, HSTS headers, and redirect logic that keys off the scheme.
$curl -fsSL https://raw.githubusercontent.com/vandot/zlodev/main/install.sh | sh
$zlodev install
$zlodev start --command="npm run dev"
zlodev will start your dev server and show logs in a split-pane below the request list. Press l to toggle logs, Tab to switch focus, j/k to scroll, and R to restart.
Your app is now at https://dev.lo
Or run your dev server separately:
$npm run dev
$zlodev start
A lightweight UDP server resolves *.lo queries to 127.0.0.1. Registers via /etc/resolver/ on macOS, systemd-resolved on Linux, and NRPT rules on Windows.
On install, zlodev generates a local CA and domain certificate. The CA is added to your system trust store, unique to your machine.
An HTTPS reverse proxy on port 443 terminates TLS, forwards plain HTTP to your dev server, and relays responses back over the encrypted connection. On Linux, file capabilities (cap_net_bind_service) allow binding to privileged ports without running as root.
A plain HTTP server on port 80 serves the CA certificate download page for mobile devices and redirects other traffic to HTTPS.
Integrated dev server launcher with live logs in the terminal UI.
Use --command="npm run dev" to let zlodev start your dev server. The process launches alongside the proxy and restarts when you press R in the logs pane.
Server output appears in a bottom pane (press l to toggle). Switch focus between requests and logs with Tab, scroll with j/k, and toggle autoscroll with s.
SIGTERM with graceful timeout, SIGKILL fallback on Unix. Job objects for clean termination on Windows. Logs continue after restart without losing history.
Store the command in your .zlodev config file: command=npm run dev. One less CLI flag to remember.
Use --route=api=3001 for subdomain routing (api.dev.lo), --route=/api=3001 for path routing, or --route=api=staging.example.com for external upstreams. Mix and match, each route gets a distinct color in the TUI.
Use -l to bind to .local via mDNS. Access your dev server from mobile devices on the same network.
Drop a .zlodev file in your project directory with port, routes, and options. No more repeating CLI flags. Use -c=PATH for a custom location.
Run with --no-tui for script and CI usage. Logs go to stderr instead of the terminal UI.
Set --max-body=50M to control how large a request body the proxy will accept. Supports K, M, G suffixes.
Works on macOS, Linux, and Windows. Written in Zig with BoringSSL for TLS. Single binary, no runtime dependencies.
zlodev replaces multiple tools with a single binary. Here's how it stacks up.
| zlodev | mkcert | Caddy | ngrok | |
|---|---|---|---|---|
| Local HTTPS with auto-certs | ✓ | ✓ | ✓ | ✓ |
| Custom local DNS (*.lo) | ✓ | ✗ | ✗ | ✗ |
| Terminal UI for traffic | ✓ | ✗ | ✗ | ✓ |
| Request interception & editing | ✓ | ✗ | ✗ | ✗ |
| Launch & monitor dev server | ✓ | ✗ | ✗ | ✗ |
| Multi-app routing | ✓ | ✗ | ✓ | ✗ |
| Single binary, no dependencies | ✓ | ✓ | ✓ | ✗ |
| Free & open source | ✓ | ✓ | ✓ | ✗ |
| No account required | ✓ | ✓ | ✓ | ✗ |
| Publicly accessible over internet | ✗ | ✗ | ✗ | ✓ |