Local Development

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 installclient

Start the inspector development server

make runclient

This starts the React-based inspector interface with hot reloading.

CLI Setup

Build the CLI binary

make buildcli

This 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

  1. Start your admin server
  2. Log in to the admin dashboard
  3. Copy your secret key from the dashboard
  4. Add it to client.dev.yaml configuration file

Test the tunnel connection

Start a test tunnel:

portr -c client.dev.yaml http 9999

Read 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 --json

Notes:

  • portr logs <subdomain> [filter] searches only by request URL substring.
  • --json emits the full stored record, including headers, status code, replay metadata, and timestamp.
  • --since accepts either RFC3339 timestamps or YYYY-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 replay only 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: 3000

Inspector 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

  1. Start all services: admin → tunnel server → client
  2. Create a test service: Run a simple HTTP server locally
  3. Create a tunnel: Use your built client to tunnel the service
  4. Test connectivity: Access the tunnel URL and verify it works
  5. 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 browser

Inspector 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       # Dependencies

The 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.