Documentation

Everything you need to know to use Unix Shells.

Getting started

Sign up at unixshells.com/signup. You'll get an email to verify your account. Once verified, log into the web terminal to provision your first shell.

Each shell is a full KVM virtual machine with Ubuntu 24.04 and 200+ tools pre-installed. It boots from a memory snapshot in seconds.

Connecting to your shell

There are four ways to connect:

1. Web terminal

Open unixshells.com/terminal in any browser. Log in with your username and password. Your shells appear in the sidebar — click to connect. Windows are draggable, resizable, and tileable.

2. SSH (via relay)

From any SSH client:

ssh -J relay.unixshells.com [email protected]

Or add this to ~/.ssh/config (run latch relay ssh-config to generate it automatically):

Host *.yourusername.unixshells.com
  ProxyJump relay.unixshells.com
  User default

Then just ssh shell-XXXX.yourusername.unixshells.com.

3. Mobile app

Install the Unix Shells app for iOS or Android. Sign in with your account. Your shells auto-discover in the sidebar — tap to connect. Supports both SSH and Mosh (for flaky connections).

4. Direct SSH (via IPv6)

If you have IPv6 connectivity, SSH directly to your shell's IPv6 address on port 2222:

ssh -p 2222 default@2604:2dc0:20a:d000::1

Your shell's IPv6 is shown in the dashboard.

Web terminal

The web terminal at unixshells.com/terminal gives you a full terminal in the browser. It feels like a local terminal — keystrokes echo instantly, even over high-latency connections.

Mosh (default)

The web terminal uses Mosh over WebTransport (HTTP/3) by default. Mosh predicts your input locally and reconciles with the server, so typing feels immediate regardless of your network latency. Your session survives Wi-Fi switches, laptop sleeps, and network interruptions without dropping a character. The connection resumes automatically.

Mosh requires WebTransport, which is supported in Chrome, Edge, Firefox, and other Chromium-based browsers. Safari does not support WebTransport yet — the web terminal falls back to SSH automatically on Safari.

SSH (fallback)

The web terminal can also connect over SSH via WebSocket. This is the traditional approach — every keystroke round-trips to the server before it appears on screen. It works everywhere but feels slower on high-latency connections. The web terminal uses SSH automatically on Safari, or you can switch to it manually in Settings.

Switching connection mode

Open the settings panel (gear icon) and toggle the Mosh switch. New connections will use the selected mode. Existing windows keep their current connection.

Features

  • Draggable, resizable floating windows (like a desktop)
  • Tile windows: grid, columns, or rows
  • Minimize to taskbar, maximize to full screen
  • Multiple shells open simultaneously
  • Clipboard support (copy/paste, OSC 52)
  • Manage shells: restart, destroy, add/remove SSH keys

Your password never leaves the browser (OPAQUE zero-knowledge authentication). Your SSH key is encrypted client-side.

Mobile app

The mobile app supports SSH, Mosh, and SFTP. It auto-discovers all your shells and relay devices.

  • Tap a device in the sidebar to connect
  • Long-press to configure Mosh and SSH key preferences
  • Manage shells: list, restart, add/remove SSH keys
  • Purchase shells via in-app purchase (Apple/Google)
  • SFTP file browser for transferring files

SSH keys

Your shell uses ~/.latch/authorized_keys for SSH authentication (same format as OpenSSH).

Add keys from the web terminal (Shells tab → Keys), the mobile app, or the CLI:

latch shells key add SHELL_ID ~/.ssh/id_ed25519.pub

List keys:

latch shells key list SHELL_ID

AI agents

Every shell comes with Claude Code, OpenAI Codex, OpenCode, OpenClaw, and Aider pre-installed. All you need is an API key.

Claude Code

Two ways to authenticate:

# Option 1: API key (simplest)
export ANTHROPIC_API_KEY="sk-ant-..."
echo 'export ANTHROPIC_API_KEY="sk-ant-..."' >> ~/.bashrc
claude

# Option 2: Anthropic account (Pro/Max subscription)
claude
# Type /login inside the REPL
# It prints a URL — open it on your phone or laptop to authenticate

Claude Code opens an interactive REPL. Type your request and it edits your code directly. Use /status to check auth, /help for commands.

Non-interactive: claude -p "add error handling to the auth module"

OpenAI Codex

Two ways to authenticate:

# Option 1: Device code (recommended — works from any headless server)
codex login --device-auth
# Prints a URL and a code
# Open the URL on your phone or laptop, enter the code, done

# Option 2: API key
export OPENAI_API_KEY="sk-..."
echo 'export OPENAI_API_KEY="sk-..."' >> ~/.bashrc
codex

Once authenticated:

cd ~/your-project
codex "explain what this codebase does"

Note: device-code auth must be enabled in your ChatGPT account security settings.

OpenCode

Set an API key for your preferred provider:

# For Claude models
export ANTHROPIC_API_KEY="sk-ant-..."

# For OpenAI models
export OPENAI_API_KEY="sk-..."

# Add to your profile so it persists
echo 'export ANTHROPIC_API_KEY="sk-ant-..."' >> ~/.bashrc

cd ~/your-project
opencode

OpenCode opens a terminal UI. Type your request or use /init to generate an AGENTS.md that gives it context about your project.

Non-interactive: opencode -p "explain the use of context in this Go project"

OpenClaw

OpenClaw runs as a persistent daemon. The onboard wizard walks you through setup in about 2 minutes:

openclaw onboard --install-daemon

The wizard asks you to pick a model provider (Anthropic, OpenAI, Google, etc.) and paste an API key. It installs a systemd user service so OpenClaw runs in the background.

After setup:

# Launch the TUI
openclaw tui

# Check the daemon is running
openclaw gateway status

# Expose the web UI on your dev preview URL
# Note: anyone with the URL can access it. Use OpenClaw's token auth.
preview 18789

# Send a message from the command line
openclaw agent --message "Hello, what can you do?"

Aider

Aider uses API keys directly. Set your key and go:

# For Claude
export ANTHROPIC_API_KEY="sk-ant-..."
echo 'export ANTHROPIC_API_KEY="sk-ant-..."' >> ~/.bashrc

cd ~/your-project
aider

Aider auto-detects your API key and picks the best available model. You can also be explicit:

aider --model sonnet
aider --model o3-mini --api-key openai=sk-...
aider --model deepseek --api-key deepseek=sk-...

Running agents in the background

All agents run inside latch sessions that persist indefinitely. Use the prefix key (Ctrl+]) to manage windows:

# Create a new window: Ctrl+] then c
# Switch windows: Ctrl+] then n (next) or p (previous)
# Detach: Ctrl+] then d

Your agent keeps running whether you're connected or not. Check in from SSH, the web terminal, or the mobile app.

Services (Docker, PostgreSQL, Redis, etc.)

Your shell has Docker, PostgreSQL, Redis, MySQL, nginx, Apache, and many other services pre-installed but disabled by default to save memory. Start any service with:

sudo systemctl start docker
sudo systemctl start postgresql
sudo systemctl start redis-server
sudo systemctl start nginx
sudo systemctl start mysql

Enable a service to auto-start on shell restart:

sudo systemctl enable docker

Your user has passwordless sudo for systemctl, ip, iptables, wg-quick, certbot, and other networking/service commands. Package management (apt) is not available — the base system is shared across VMs via copy-on-write. Install tools into your home directory with pip install --user, cargo install, go install, npm install -g, etc.

Dev preview URLs

Every shell gets a unique subdomain for sharing web apps. Start a web server on any port:

python3 -m http.server 8000
# or
npx serve .
# or
npm run dev

Your preview URL is shown in the dashboard (e.g., abc123.konoha.unixshells.sh). Share it with anyone:

  • IPv6 clients connect directly to your shell on any port
  • IPv4 clients go through our reverse proxy on ports: 80, 443, 1234, 3000, 3001, 3030, 4000, 4173, 4200, 4321, 5000, 5173, 5174, 8000, 8001, 8888, 9000

Works with any framework — Next.js, Flask, Rails, Express, anything that binds a port.

Custom domains

Point your own domain at your shell with two DNS records:

  1. An AAAA record pointing to your shell's IPv6 address (shown in the dashboard)
  2. An A record pointing to the shell host's IPv4 address (shown in the dashboard)

IPv6 clients connect directly. IPv4 clients go through our reverse proxy automatically. No tunnels, no config files.

For HTTPS, run certbot inside your shell:

sudo certbot certonly --standalone -d yourdomain.com

You can also use Cloudflare Tunnel, Tailscale, or WireGuard if you prefer.

Public IPv6

Each shell has its own /128 IPv6 address with direct internet connectivity. No NAT, no tunnels. Your IPv6 is shown in the dashboard.

You can bind any port on your IPv6 address and it's reachable from the internet. Run a web server, API, game server — anything.

# Check your IPv6
ip -6 addr show dev eth0 scope global

# Test connectivity
curl -6 https://ifconfig.me

Relay (NAT traversal)

The relay lets you SSH to any machine behind NAT — your shell, your laptop, your home server. It's a dumb pipe: all traffic is end-to-end encrypted SSH ciphertext.

Setup on any device

# First device — create account
latch relay register

# Additional devices
latch relay add

This generates a relay key at ~/.latch/relay.key and writes the relay config. The device appears in your account's device list.

Connect to a device

# Via SSH
ssh -J relay.unixshells.com [email protected]

# Generate SSH config
latch relay ssh-config >> ~/.ssh/config

Check status

latch relay status

latch basics

latch is the terminal multiplexer running inside your shell. It keeps sessions alive across disconnects. Think tmux, but with built-in SSH and web access.

Key bindings

Prefix key: Ctrl+] then:

  • c — new window
  • n / p — next / previous window
  • 0-9 — select window by number
  • x — close window
  • d — detach
  • s — admin panel

CLI commands

# List sessions
latch ls

# New named session
latch new work

# Attach to a session
latch attach work

# Kill a session
latch kill work

Persistence

Your home directory (~/) persists across VM restarts. Code, configs, databases, SSH keys — everything in your home directory stays.

The system overlay (everything outside ~/) resets on restart. This means apt install changes won't persist, but that's by design — the base system is shared via copy-on-write for fast boot and memory efficiency.

Install tools into your home directory instead:

pip install --user mypackage
cargo install mytool
go install github.com/user/tool@latest
npm install -g mypackage

FAQ

How do I run Docker?

sudo systemctl start docker
docker run hello-world

How do I start a database?

sudo systemctl start postgresql
# or
sudo systemctl start redis-server
# or
sudo systemctl start mysql

Can I use VS Code Remote SSH?

Yes. Add your shell to your SSH config (run latch relay ssh-config) and use VS Code's Remote SSH extension to connect.

Can I use WireGuard or Tailscale?

Yes. Full TUN/TAP support with passwordless sudo for wg-quick and ip.

sudo wg-quick up wg0
# or
tailscale up

How do I get SSL certificates?

sudo certbot certonly --standalone -d yourdomain.com

What's my shell's IPv6 address?

Shown in the dashboard, or run ip -6 addr show dev eth0 scope global inside the shell.

How much storage do I have?

Shell: 10 GB. Shell+: 25 GB. The 200+ pre-installed tools don't count against your quota — they're in the shared memory snapshot.