█ █ █▀▀█ █▀▀█ █▀▄▀█ █ █ █▀▀█ █ █▀▀ █▄█▄█ █ █ █▄▄▀ █ █ █ █▀▀█ █ █ █ █▀▀ ▀ ▀ ▀ ▀▀▀▀ ▀ ▀▀ ▀ ▀ ▀ ▀ ▀▀▀▀ ▀▀▀ ▀▀▀
Expose your localhost to the internet. Instantly.
Wormhole is an open-source ngrok alternative that gives your local server a public HTTPS URL with a single command. No signup required. No config files. Just works.
wormhole http 3000 █ █ █▀▀█ █▀▀█ █▀▄▀█ █ █ █▀▀█ █ █▀▀
█▄█▄█ █ █ █▄▄▀ █ █ █ █▀▀█ █ █ █ █▀▀
▀ ▀ ▀ ▀▀▀▀ ▀ ▀▀ ▀ ▀ ▀ ▀ ▀▀▀▀ ▀▀▀ ▀▀▀
v0.1.0
╭──────────────────────────────────────────────────╮
│ Status ● connected │
│ Forwarding https://k7x9m2.wormhole.bar → ... │
│ Inspector http://localhost:4040 │
╰──────────────────────────────────────────────────╯
Requests
--------------------------------------------------------------
GET / 200 12ms
POST /webhooks/stripe 200 8ms
GET /api/users 200 34ms
- One command —
wormhole http 3000and you're live - HTTPS by default — TLS handled automatically by Cloudflare
- Custom subdomains —
wormhole http 3000 --subdomain myapp(free with GitHub login) - Traffic inspector — Built-in dashboard at
localhost:4040with live request stream - Request replay — Re-send any captured request with one click
- HAR export — Export captured traffic in standard HAR format
- Color-coded terminal — Live request log with method + status code colors
- Auto-reconnect — Exponential backoff, seamless recovery
- WebSocket passthrough — Full WebSocket support through the tunnel
- Zero config — No signup, no config file, no server to deploy
- Open source — Fully open source, MIT licensed
curl -fsSL https://wormhole.bar/install.sh | shbrew install MuhammadHananAsghar/tap/wormholego install github.com/MuhammadHananAsghar/wormhole/cmd/wormhole@latestgit clone https://github.com/MuhammadHananAsghar/wormhole.git
cd wormhole
make build
# Binary: ./wormhole# Start your local server on any port
wormhole http 3000
# => https://k7x9m2.wormhole.bar -> http://localhost:3000# One-time login via GitHub
wormhole login
# Use your own subdomain
wormhole http 3000 --subdomain myapp
# => https://myapp.wormhole.bar -> http://localhost:3000Every tunnel automatically starts a traffic inspector at http://localhost:4040:
- Live request/response stream via WebSocket
- Request detail view with headers and body
- One-click request replay
- Filter by method, status code, path
- Export as HAR file
# Custom inspector port
wormhole http 3000 --inspect localhost:5050
# Disable inspector
wormhole http 3000 --no-inspectwormhole http <port> # Expose local HTTP server
wormhole http <port> --subdomain NAME # Custom subdomain
wormhole http <port> --headless # No TUI, plain log output
wormhole http <port> --inspect ADDR # Custom inspector address
wormhole http <port> --no-inspect # Disable inspector
wormhole login # Authenticate via GitHub
wormhole logout # Remove stored credentials
wormhole status # Show auth status
wormhole uninstall # Remove wormhole from system
wormhole uninstall --purge # Also remove config (~/.wormhole/)
wormhole version # Print versionYOUR LAPTOP CLOUDFLARE EDGE (300+ cities)
┌──────────────┐ ┌─────────────────────────────┐
│ │ WebSocket │ │
│ wormhole │◄───────────────►│ Worker (request router) │
│ client │ (encrypted) │ ↕ │
│ │ │ Durable Object (tunnel) │
│ localhost │ │ • Holds your WebSocket │
│ :3000 │ │ • Proxies HTTP to you │
└──────────────┘ │ • Hibernates when idle │
└──────────────┬──────────────┘
│
*.wormhole.bar (Cloudflare DNS)
│
Public Internet
- Client opens WebSocket to nearest Cloudflare edge
- Durable Object assigns a subdomain
- HTTP requests to
*.wormhole.barhit the Worker - Worker routes to the correct Durable Object
- DO serializes the request over WebSocket to your client
- Client forwards to
localhost:3000 - Response flows back the same path
Latency: client <-> nearest CF edge (~5-20ms) + localhost (~0ms) = fast.
| Component | Technology |
|---|---|
| CLI Client | Go, Cobra, Bubbletea, Lipgloss |
| Transport | WebSocket (gorilla/websocket) |
| Edge Relay | Cloudflare Workers + Durable Objects |
| Database | Cloudflare D1 (SQLite) |
| DNS | Cloudflare DNS (wildcard *.wormhole.bar) |
| TLS | Cloudflare automatic SSL |
| Auth | GitHub OAuth |
wormhole/
├── cmd/wormhole/ # CLI entry point
├── internal/
│ ├── client/ # Tunnel client (connect, forward, display)
│ ├── transport/ # WebSocket transport layer
│ └── inspect/ # Traffic inspector (recorder, server, replay, HAR)
├── edge/ # Cloudflare Worker + Durable Object relay
│ ├── src/
│ │ ├── index.ts # Worker router + auth
│ │ └── tunnel.ts # Durable Object tunnel proxy
│ └── migrations/ # D1 schema migrations
├── pkg/config/ # User config (~/.wormhole/config.json)
├── deployments/ # install.sh, Docker, etc.
├── Makefile
└── .goreleaser.yml
# Run all Go tests
go test ./... -race
# Run edge tests
cd edge && npm test
# Build binary
make build
# Cross-compile all platforms
make distThis project follows test-driven development. Write failing tests first, then implement.
# Run tests in watch mode
go test ./internal/inspect/ -v -count=1
# Coverage
go test ./... -cover| Feature | ngrok (free) | Cloudflare Tunnel | Wormhole |
|---|---|---|---|
| One-command setup | Needs signup | Needs CF account | Just works |
| Custom subdomains | Paid ($8/mo) | Yes (complex) | Free |
| HTTPS | Yes | Yes | Yes |
| Traffic inspector | Basic | No | Full (replay, HAR) |
| WebSocket support | Yes | Yes | Yes |
| Open source | No | Client only | Fully open source |
| Cost | $0-$120/yr | $0 (complex) | $0 |
Wormhole is built on a dual-track architecture: Cloudflare Workers (free, no setup) + self-hosted Go relay (full control, unlimited scale).
- Phase 1 — Core tunnel (
wormhole http 3000→ public URL, WebSocket passthrough) - Phase 2 — HTTPS, custom subdomains (auto-reserve, 3/user limit), GitHub OAuth
- Phase 3 — Traffic inspector, request replay, HAR export, curl generation
- Phase 4 — Self-hosted Go relay (
wormhole server, QUIC transport, SQLite persistence) - Phase 5 — Auth & multi-user (API keys, team tokens, CF + self-hosted middleware)
- Phase 6 — Stream multiplexing (virtual streams over single WebSocket, backpressure)
- Phase 7 — Plugin system (request/response pipeline, custom auth, transforms)
- Phase 8 — Observability (Prometheus metrics, structured logs, health endpoints)
- Phase 9 — Protocol evolution (version negotiation, TLS pinning, binary framing)
- Phase 10 — Enterprise hardening (connection limits, mTLS, audit logs, RBAC)
- Phase 11 — P2P mode (
wormhole share, WebRTC direct connections, no relay) - Phase 12 — Polish & ship (homepage, docs site, video demos, package registries)
Muhammad Hanan Asghar
- GitHub: @MuhammadHananAsghar
- LinkedIn: muhammadhananasghar
MIT License. See LICENSE for details.
Built with Go + Cloudflare Workers. Runs on the edge.