CLI Usage Guide
Overview
The Jetty CLI is your command-line companion for securely exposing local development servers to the internet. Whether you're testing webhooks, sharing work with clients, or debugging mobile apps against your local backend, jetty makes it simple.
What it does:
- Creates secure HTTPS tunnels from the internet to your local development server
- Provides stable URLs for webhook testing and team collaboration
- Captures and replays HTTP requests for debugging
- Works with any HTTP server: Laravel, Rails, Next.js, Vite, Django, and more
Why use it:
- No ngrok subscription needed--you control your own infrastructure
- Team-friendly with reserved subdomains and custom domains
- Built-in request inspection and replay
- First-class Laravel integration with automatic detection
Installation Recap
The Jetty CLI can be installed via our installation script or Composer. For detailed installation instructions, see the Installation Guide.
Quick install (recommended):
curl -fsSL "https://usejetty.online/install/jetty.sh" | bash
Via Composer (global):
composer global require jetty/client
Verify installation:
jetty version
Shell Completions
Enable tab completion for commands, flags, and arguments:
Bash (add to ~/.bashrc):
eval "$(jetty completions bash)"
Zsh (add to ~/.zshrc):
eval "$(jetty completions zsh)"
Fish (one-time setup):
jetty completions fish > ~/.config/fish/completions/jetty.fish
After installation, press Tab to complete commands (jetty sha -> jetty share), flags (jetty share --sub -> jetty share --subdomain=), and config keys (jetty config set ser -> jetty config set server).
Diagnostics
The jetty doctor Command
Run jetty doctor to check that your environment is configured correctly:
jetty doctor
It verifies:
- PHP installation -- correct version (8.2+) and required extensions
- CLI version -- whether you are running the latest release
- PATH -- that the
jettybinary is reachable - API connectivity -- that your configured server is reachable over HTTPS
- Auth token -- that a valid token is set and accepted by the server
A passing check prints a green checkmark; a failing check prints the cause and numbered fix suggestions.
Structured Error Messages
When any jetty command fails, the CLI prints a structured error with:
- What went wrong -- a one-line summary of the error
- Suggested fixes -- numbered steps you can try
Example output:
Error: Connection refused (127.0.0.1:8000)
1. Make sure your local server is running on port 8000
2. Check for firewall rules blocking localhost connections
3. Run "jetty doctor" to verify your setup
Common Errors
| Error | Cause | Suggested Fixes |
|---|---|---|
| Connection refused | Local server is not running or wrong port | Start your server; verify the port matches |
| Auth failed (401) | Token is invalid or revoked | Run jetty config set token NEW_TOKEN; check the Tokens page in the dashboard |
| Tunnel limit reached (402/429) | Plan tunnel cap exceeded | Delete unused tunnels with jetty delete; upgrade your plan |
| DNS resolution failed | Server name is wrong or unreachable | Check jetty config get server; verify your internet connection |
| TLS handshake error | Certificate issue on the server | Ensure the server has a valid SSL certificate; try curl to the API URL manually |
Basic Commands
Getting Help
The help command shows available commands and options:
# Show main help
jetty help
# Show advanced options and environment variables
jetty help --advanced
# Get help on a specific command
jetty help share
You can also use the --help flag on any command:
jetty share --help
jetty config --help
Checking Your Version
Always good to know what version you're running:
# Show version
jetty version
# Show version with install method details
jetty version --install
# Check for updates without installing
jetty version --check-update
The output shows your CLI version and how it was installed (PHAR, Composer global, or project dependency).
Updating the CLI
Keep your CLI up to date with the latest features and fixes:
# Update to the latest version
jetty update
# Alternative command (same thing)
jetty self-update
How it works:
- PHAR installs pull the latest release from GitHub
- Composer installs run
composer update jetty/clientin the project
Updates are version-aware--you'll only download what's needed.
Configuration
First Time Setup
When you first run jetty, you'll be guided through a quick setup:
jetty setup
This interactive wizard helps you configure:
- Server name -- which Jetty deployment to use (from your team's dashboard)
- API token -- your personal access token for authentication
You can also configure manually:
# Set your server
jetty config set server your-server-name
# Set your token
jetty config set token your-token-here
# View current config
jetty config
Pro tip: Get your server name and token from the Getting Started page in your Jetty dashboard--it has copy-paste commands ready to go!
Config File vs Environment Variables
Jetty uses a flexible configuration system with multiple layers:
Config file (recommended for most users):
- Global:
~/.config/jetty/config.json - Project-specific:
jetty.yml(orjetty.yaml,jetty.config.json,.jetty.json) in your project root - Survives terminal sessions
- Easy to version control (project configs)
YAML (recommended for projects):
# jetty.yml
share:
subdomain: my-app
tunnel_server: us-east-1
JSON (global config):
{
"api_url": "https://your-jetty.example",
"token": "your-personal-access-token"
}
Environment variables (good for CI/CD):
export JETTY_SERVER=your-server-name
export JETTY_TOKEN=your-token-here
export JETTY_API_URL=https://your-jetty.example
Command-line flags (one-off overrides):
jetty share 8000 --token=different-token --api-url=https://staging.jetty.example
Precedence (highest to lowest):
- Command-line flags
- Environment variables
- Project config file (
jetty.yml/jetty.config.json) - Global config file (
~/.config/jetty/config.json)
Multiple Environments
Managing dev, staging, and production environments is straightforward:
Option 1: Project-specific configs
Create a jetty.config.json in each project:
cd ~/projects/my-app
jetty config set server dev-server
jetty config set token dev-token-here
Option 2: Shell aliases
Add to your ~/.zshrc or ~/.bashrc:
alias jetty-staging='JETTY_SERVER=staging JETTY_TOKEN=staging-token jetty'
alias jetty-prod='JETTY_SERVER=prod JETTY_TOKEN=prod-token jetty'
Then use:
jetty share 8000 # Uses default config
jetty-staging share 8000 # Uses staging
jetty-prod share 8000 # Uses production
Option 3: Multiple config files
jetty --config=~/.config/jetty/staging.json share 8000
jetty --config=~/.config/jetty/prod.json share 8000
Sharing Tunnels
Basic Share
The simplest way to share your local server:
# Share port 8000
jetty share 8000
This:
- Registers a tunnel with the Jetty bridge
- Connects the WebSocket agent to the edge server
- Gives you a public HTTPS URL like
https://reef-abc123.tunnels.usejetty.online
Keep the terminal open while you test--when you close it, the tunnel stays registered but HTTP forwarding stops.
Common ports:
jetty share 8000 # Laravel artisan serve
jetty share 3000 # Next.js, Express, Vite
jetty share 4000 # Rails
jetty share 5173 # Vite default
jetty share 8080 # Many Java apps
With Subdomain
For stable URLs (great for webhooks), use a reserved subdomain:
jetty share 8000 --subdomain=my-app
This gives you: https://my-app.tunnels.usejetty.online
The subdomain persists across restarts, so your webhook URLs stay valid.
Reserve subdomains in your Jetty dashboard under Domains -> Reserved Subdomains.
With Custom Domain
If you've configured a custom domain in your Jetty dashboard:
jetty share 8000 --domain=dev.mycompany.com
This requires DNS and SSL setup on your Jetty deployment. See Custom Domains for configuration details.
Specifying Upstream
By default, jetty share forwards to 127.0.0.1:PORT. For different hosts:
# Explicit localhost
jetty share 3000 --site=127.0.0.1
# Another device on your LAN
jetty share 8080 --site=192.168.1.100
# Valet/Herd local domain
jetty share 80 --site=my-app.test
jetty share 443 --site=my-app.test
# Docker container (use host.docker.internal or IP)
jetty share 8000 --site=172.17.0.2
Aliases for --site:
--bind=--local=--local-host=
Laravel Detection
Jetty automatically detects Laravel applications and sets up intelligent URL rewriting:
What's detected:
- Projects with an
artisanfile in the current or parent directories APP_URLfrom your.envfile- Common Valet/Herd hostnames (
.test,.localhost)
Why it matters:
Laravel often redirects to APP_URL. Jetty rewrites these redirects so your browser stays on the tunnel URL instead of jumping to http://localhost:8000 or https://my-app.test.
Example:
cd ~/projects/my-laravel-app
jetty share 8000
# Detected Laravel
# Found APP_URL: https://my-app.test
# Will rewrite redirects to tunnel URL
Manual override:
# Add additional hosts to rewrite
JETTY_SHARE_REWRITE_HOSTS=api.myapp.test,admin.myapp.test jetty share 8000
Managing Tunnels
Listing Active Tunnels
See all your tunnels:
jetty list
Output shows:
- Tunnel ID
- Public URL
- Local upstream
- Status (connected/disconnected)
- Sample count (requests captured)
- Created date
Filtering:
# List only your tunnels
jetty list
# Include team tunnels
jetty list --all
Deleting a Tunnel
Remove a tunnel you no longer need:
# Delete by ID
jetty delete abc123xyz
# Delete by URL
jetty delete https://reef-abc123.tunnels.usejetty.online
Auto-delete on exit:
# Automatically delete tunnel when you exit jetty share
jetty share 8000 --delete-on-exit
# Or set the environment variable
JETTY_SHARE_DELETE_ON_EXIT=1 jetty share 8000
Resuming a Previous Tunnel
By default, Jetty tries to resume your most recent tunnel when you run jetty share again with the same local upstream:
# First run - creates new tunnel
jetty share 8000 --subdomain=my-app
# Got: https://my-app.tunnels.usejetty.online
# Stop with Ctrl+C
# Second run - resumes the same tunnel
jetty share 8000 --subdomain=my-app
# Got: https://my-app.tunnels.usejetty.online (same URL!)
Disable resume:
JETTY_SHARE_NO_RESUME=1 jetty share 8000
How it works:
Jetty matches tunnels by local_host:local_port. For Valet/Herd hostnames, ports 80 and 443 are considered equivalent so switching between HTTP and HTTPS doesn't create duplicate tunnels.
For debugging, advanced workflows, environment variables, and troubleshooting, see CLI Advanced Usage.
Send feedback
Found an issue or have a suggestion? Let us know.