A simple HTTP tunneling tool that exposes your local development server to the internet through custom subdomains.
Wormhole creates a tunnel between your local development server and the internet, allowing you to:
- Share your local web application with others instantly
- Test webhooks and APIs that require public URLs
- Demo your work-in-progress applications
- Access your local development environment from anywhere
go run cmd/server/main.gogo run cmd/client/main.go -domain=myapp -local=http://localhost:3000Your local server is now available at: http://myapp.localhost:8080
Download the latest release for your platform from the Releases page.
Linux:
tar -xzf wormhole-client-linux-amd64.tar.gz
chmod +x wormhole
./wormhole -domain=myapp -local=http://localhost:3000macOS:
The binaries are not signed with an Apple Developer certificate. After downloading, you need to remove the quarantine attribute:
tar -xzf wormhole-client-darwin-arm64.tar.gz
xattr -d com.apple.quarantine wormhole
chmod +x wormhole
./wormhole -domain=myapp -local=http://localhost:3000Alternatively, you can right-click the binary in Finder, select "Open", and confirm in the dialog.
git clone https://github.com/dbackowski/wormhole.git
cd wormhole
go mod download
make buildgo run cmd/server/main.go -port=8080Required flags:
-port: Port to run the server on (default: 8080)
Optional flags:
-debug: Enable debug mode-version: Print version and exit
go run cmd/client/main.go -server=http://localhost:8080 -domain=mysubdomain -local=http://localhost:3000Required flags:
-domain: Your unique subdomain name-local: URL of your local development server
Optional flags:
-server: Server URL (default: https://wormhole.tools)-webui-port: Port for the Web UI dashboard (default: 4040)-version: Print version and exit
✅ Custom Subdomains - Choose your own subdomain name
✅ Real-time Tunneling - Instant request forwarding via WebSockets
✅ Header Preservation - Complete HTTP headers are maintained
✅ Multiple Clients - Support for multiple simultaneous tunnels
✅ Automatic Cleanup - Domains are released when clients disconnect
✅ Web UI Dashboard - Monitor tunneled requests in a browser at http://localhost:4040
- Frontend Development: Share your React/Vue/Angular app with team members
- API Testing: Test webhook endpoints from external services
- Mobile Development: Test your local API with mobile apps
- Client Demos: Show work-in-progress to clients without deployment
When the client is running, a dashboard is available at http://localhost:4040 where you can:
- See the active tunnel URL
- View recent requests with method, path, status code, and timestamp
- Inspect request/response headers and bodies
To use a different port:
go run cmd/client/main.go -domain=myapp -local=http://localhost:3000 -webui-port=5050graph TD
A[Browser] -->|HTTP Request| B[Wormhole Server<br>myapp.server:8080]
B -->|WebSocket| C[Wormhole Client]
C -->|HTTP| D[Local Dev Server<br>localhost:3000]
D -->|Response| C
C -->|WebSocket| B
B -->|HTTP Response| A
- The server listens for client connections and HTTP requests
- Clients connect via WebSocket and claim a subdomain
- HTTP requests to
subdomain.server:portare forwarded to the client over WebSocket - The client forwards requests to your local server and returns responses
| Endpoint | Description |
|---|---|
/ws |
WebSocket endpoint for client connections |
/health |
Health check, returns OK |
/metrics |
Active connection count |
/* |
All other requests are tunneled to the matching subdomain client |
To run your own Wormhole server, you need:
- Wildcard DNS - Point
*.yourdomain.comto your server so that subdomain-based routing works - TLS termination - Wormhole does not handle TLS natively. Use a reverse proxy like Caddy or nginx to terminate TLS
- Run the server:
./wormhole-server -port=8080
docker build -t wormhole .
docker run -p 8080:8080 wormholeThe repository includes a fly.toml for deployment to Fly.io. Set your FLY_API_TOKEN as a GitHub secret for automatic deploys on push to main.
- No authentication - Any client can claim any available subdomain
- No WebSocket passthrough - WebSocket upgrade requests to tunneled services are not supported
- No built-in TLS - Requires a reverse proxy for HTTPS
- 10 MB request body limit - Requests larger than 10 MB are rejected
- 10 second request timeout - Requests that take longer than 10 seconds will time out
- Go 1.25 or later
- Available port for the server (default: 8080)
- Local development server to tunnel
Released under the MIT License.
Feel free to open issues and submit pull requests to improve Wormhole!


