Client Development Setup
Learn how to setup portr client for local development
The Portr client is built using Go for the CLI backend and includes a React + shadcn inspector for HTTP tunnels.
Requirements
- Go (1.25+)
- Bun (1.3+)
- Running admin server (for authentication)
- Running tunnel server (for tunnel connections)
Frontend Setup (Inspector)
Install frontend dependencies
make installclientStart the inspector development server
make runclientThis starts the React-based inspector interface with hot reloading.
CLI Setup
Build the CLI binary
make buildcliThis creates the portr binary in the current directory. The examples below
assume the binary is available on your PATH. From tunnel/, you can do that
during local development with export PATH="$PWD:$PATH".
Configure authentication
- Start your admin server
- Log in to the admin dashboard
- Copy your secret key from the dashboard
- Add it to
client.dev.yamlconfiguration file
Test the tunnel connection
Start a test tunnel:
portr -c client.dev.yaml http 9999Read request logs from the CLI
The client stores HTTP request logs locally in ~/.portr/db.sqlite. Coding agents
can read them directly with portr logs without opening the inspector UI.
# Show the latest 20 logs for a subdomain
portr logs amal-test
# Emit full stored request records as JSON
portr logs amal-test --jsonNotes:
portr logs <subdomain> [filter]searches only by request URL substring.--jsonemits the full stored record, including headers, status code, replay metadata, and timestamp.--sinceaccepts either RFC3339 timestamps orYYYY-MM-DD.- Full CLI documentation lives at Request Logs.
Replay stored requests from the CLI
The client can also replay a stored HTTP request from the same local request log database. This is useful for iterating on handlers without manually reproducing the same inbound request each time.
# Replay an exact stored request
portr replay 01KNAAZ6QTV77WBH91A5Z63BZZ
# Replay the latest matching request from a subdomain
portr replay --latest --subdomain amal-test --filter /api/Notes:
portr replayonly works for stored HTTP requests.- If you override the body of a request, the method does not change automatically.
- Full CLI documentation lives at Request Replay.
Development Workflow
Client Architecture
The client consists of:
- CLI interface: Command-line tool for creating tunnels
- Inspector frontend: React + shadcn web interface for HTTP and WebSocket inspection
- Tunnel manager: Handles SSH connections and port forwarding
Available Commands
# Install inspector dependencies
make installclient
# Run inspector in development mode
make runclient
# Build the CLI binary
make buildcli
# Build inspector for production
make buildclient
# Run client tests
go test ./...Configuration Files
client.dev.yaml
Development configuration for the CLI:
server_url: localhost:8001
ssh_url: localhost:2222
secret_key: your_secret_key_here
tunnels:
- name: test
subdomain: test
port: 3000Inspector Configuration
The inspector runs on http://localhost:7777 by default and automatically connects to active HTTP tunnels. You can change that with dashboard_port in client.dev.yaml or use disable_dashboard: true to skip starting it.
Testing Your Changes
Unit Tests
Run the client test suite:
go test ./...Integration Testing
- Start all services: admin → tunnel server → client
- Create a test service: Run a simple HTTP server locally
- Create a tunnel: Use your built client to tunnel the service
- Test connectivity: Access the tunnel URL and verify it works
- Test inspector: Check that HTTP requests appear in the inspector
Manual Testing
# Start a simple HTTP server for testing
python -m http.server 8080
# In another terminal, create a tunnel
portr -c client.dev.yaml http 8080
# Test the tunnel URL in your browserInspector Development
The inspector is a React application that provides:
- Real-time request monitoring: View HTTP requests as they happen
- Request details: Headers, body, timing information
- Request replay: Resend requests or edit them before replaying
- WebSocket support: Monitor WebSocket connections
Inspector Structure
internal/client/dashboard/ui-v2/
├── src/ # React source code
├── public/ # Static assets
├── dist/ # Embedded Go assets
└── package.json # DependenciesThe inspector automatically starts when you create an HTTP tunnel and is
accessible at http://localhost:7777 by default.
Troubleshooting
Build Issues
Go build errors: Ensure you're using Go 1.25+ and all dependencies are available.
Frontend build errors: Verify Bun is installed, then try deleting node_modules and reinstalling.
Runtime Issues
Connection refused: Make sure the tunnel server is running and accessible.
Authentication failures: Verify your secret key is correct and the admin server is running.
Inspector not loading: Check that your configured dashboard port is available and the frontend build completed successfully. If you do not want the inspector at all, set disable_dashboard: true.