Skip to main content
This guide walks you through running the complete Wormkey infrastructure on your local machine. The stack consists of three components that work together to create secure tunnels to your localhost.

Architecture Overview

ComponentPortRole
Control Plane3001Session creation, slug allocation, lifecycle management
Gateway3002TLS termination, routing, stream forwarding
CLIConnects to gateway, forwards traffic to localhost

Prerequisites

  • Node.js 18+ and npm
  • Go 1.20+
  • Git

Installation

1

Clone the repository

git clone https://github.com/your-org/wormkey.git
cd wormkey
2

Install dependencies

Use the Makefile to install all dependencies at once:
make install
Or install each component manually:
# CLI dependencies
cd packages/cli && npm install

# Control Plane dependencies
cd packages/control-plane && npm install

# Gateway dependencies
cd packages/gateway && go mod download
3

Configure environment variables

Copy the example environment file:
cp .env.example .env
For local development, the defaults work out of the box:
# CLI (local dev)
WORMKEY_CONTROL_PLANE_URL=http://localhost:3001
WORMKEY_EDGE_URL=ws://localhost:3002/tunnel

# Control plane env
WORMKEY_PUBLIC_BASE_URL=http://localhost:3002
WORMKEY_EDGE_BASE_URL=ws://localhost:3002
See Environment Variables for all configuration options.
4

Start the Control Plane

In your first terminal:
make control-plane
Or manually:
cd packages/control-plane && npm run dev
You should see:
Control plane listening on :3001
5

Start the Gateway

In a second terminal:
make gateway
Or manually:
cd packages/gateway && go run .
You should see:
listening on 0.0.0.0:3002
6

Build and install the CLI

In a third terminal:
cd packages/cli
npm install
npm run build
npm link
This makes the wormkey command available globally.

Testing Your Setup

1

Start a local server

In a new terminal, start any local web server. For example:
# Example: Start a simple HTTP server
python3 -m http.server 3000
2

Open a wormhole

In another terminal, expose your local server:
wormkey http 3000
You’ll see output like:
Wormhole open.
http://localhost:3002?slug=quiet-lime-82
Owner claim URL (open once):
http://localhost:3002/.wormkey/owner?slug=quiet-lime-82&token=...
Path B integration (add in app layout):
<script defer src="http://localhost:3002/.wormkey/overlay.js?slug=quiet-lime-82"></script>
3

Access your tunneled server

Open the public URL in your browser. You should see your local server!To enable owner controls, open the owner claim URL once in your browser. This sets a cookie that identifies you as the tunnel owner.

Development Workflow

Hot Reload

Both the control plane and gateway support hot reload:
  • Control Plane: Uses npm run dev with auto-reload on file changes
  • Gateway: Restart with go run . after making changes
  • CLI: Rebuild with npm run build after changes

Running Tests

make test

Building for Production

make build
This compiles:
  • CLI: packages/cli/dist/
  • Control Plane: packages/control-plane/dist/
  • Gateway: Binary compilation via go build

CLI Usage

Once installed, the CLI provides these commands:
# Expose a local port
wormkey http <port>

# With authentication
wormkey http 3000 --auth

# With custom expiration
wormkey http 5173 --expires 30m
In v0, some commands are not yet implemented:
  • wormkey login - Authentication (not implemented)
  • wormkey status - View active tunnels (not implemented)
  • wormkey close - Use Ctrl+C to close tunnels

Troubleshooting

Control Plane won’t start

  • Check port 3001 is not in use: lsof -i :3001
  • Verify Node.js version: node --version (requires 18+)
  • Check logs for specific errors

Gateway won’t start

  • Check port 3002 is not in use: lsof -i :3002
  • Verify Go version: go version (requires 1.20+)
  • Ensure dependencies are installed: go mod download

CLI can’t connect

  • Verify control plane is running on port 3001
  • Verify gateway is running on port 3002
  • Check environment variables in .env
  • Ensure WebSocket connections are allowed (no proxy blocking)

Tunnel disconnects immediately

  • Check that your local server is actually running on the specified port
  • Verify firewall isn’t blocking localhost connections
  • Check gateway logs for connection errors

Next Steps

Build docs developers (and LLMs) love