Skip to content

termpod/termpod

TermPod

CI License: MIT

Your terminal, everywhere.

TermPod is a shared terminal app for developers. Start a session on your Mac — run Claude Code, Codex, or any CLI tool — and pick it up on your iPhone. Both devices see the same live terminal. Type from either one.

No SSH. No tmux hacks. No VPN. Just open the app.

How It Works

                    ┌────────────────┐
                    │  TermPod Relay │
                    │  (Cloudflare   │
                    │   Durable Obj) │
                    └───▲────────▲───┘
                   ws   │        │  ws
           ┌────────────┘        └────────────┐
           │                                  │
     ┌─────▼───┐  bonjour / webrtc (P2P)  ┌──▼──────┐
     │   Mac   │◄────────────────────────►│  iPhone │
     │ (PTY +  │                          │ (viewer │
     │  viewer)│                          │ + input)│
     └─────────┘                          └─────────┘

Your Mac runs the actual shell. Devices connect in the fastest way available:

  1. Local WebSocket — Same LAN? Direct connection via Bonjour (~1-5ms)
  2. WebRTC P2P — Different networks? Peer-to-peer data channel via STUN/TURN (~10-30ms)
  3. Relay — Fallback through Cloudflare (~30-80ms)

Sessions survive disconnects — close the app, reopen it, and you're right where you left off.

Features

  • Shared sessions — Same terminal on Mac and iPhone, real-time
  • Scrollback sync — Connect your phone mid-session, see everything that happened
  • Quick actions — Accept/deny prompts, Ctrl+C, Enter — one tap on mobile
  • Local P2P — Direct connection over LAN via Bonjour (no relay needed)
  • WebRTC P2P — Peer-to-peer across networks via STUN/TURN, relay as fallback
  • Multi-session tabs — Multiple terminal sessions, each in its own tab
  • Session management — Named by project directory, device-aware
  • Auto-updates — Desktop app updates automatically via relay proxy
  • E2E encryption — Relay transport encrypted with ECDH + AES-256-GCM; relay can't read your data
  • Local auth — Bonjour connections authenticated via shared secret exchanged over relay
  • Password reset — Email-based 6-digit code reset via Resend
  • Error tracking — Sentry integration across desktop, relay, and iOS
  • Works with everything — Claude Code, Codex, npm, docker, any CLI

Configuration

All user settings are stored as JSON in ~/.termpod/:

~/.termpod/
├── config.json          # Appearance, terminal, behavior settings
├── keybindings.json     # Custom keyboard shortcut overrides
├── workflows.json       # Saved command workflows
└── themes/              # Drop custom theme .json files here

Edit these files in any text editor — changes are picked up live, no restart needed. Custom themes appear automatically in the theme picker. See the Customization docs for the full reference.

Tech Stack

Layer Technology
Desktop app Tauri 2.0 + React + xterm.js
Mobile app Native SwiftUI + SwiftTerm
PTY tauri-plugin-pty (Rust)
Relay Cloudflare Workers + Durable Objects
Protocol WebSocket (binary frames for data, JSON for control)
Transport Device-level multiplexed connections (single WS per transport)
Auth JWT (HS256)
Security E2E: ECDH P-256 + AES-256-GCM (relay), DTLS (WebRTC), shared secret (local)
Local transport Bonjour / mDNS
P2P transport WebRTC DataChannel (livekit/webrtc)
Auto-update tauri-plugin-updater via relay proxy

Project Structure

termpod/
├── apps/
│   ├── desktop/          # Tauri 2.0 macOS app
│   │   ├── src/          # React frontend
│   │   ├── src-tauri/    # Rust backend + PTY management
│   │   └── package.json
│   └── ios/              # Native iOS app (SwiftUI + SwiftTerm)
│       ├── TermPod/      # Swift source
│       ├── project.yml   # XcodeGen project spec
│       └── generate-config.sh
├── packages/
│   ├── ui/               # Shared React components
│   ├── protocol/         # WebSocket message types + binary encoding
│   └── shared/           # Constants, types, utilities
├── relay/                # Cloudflare Worker + Durable Objects
│   ├── src/
│   │   ├── worker.ts     # Entry point, auth, routing
│   │   ├── user.ts       # User DO (device control plane, session mgmt)
│   │   ├── session.ts    # TerminalSession DO (binary relay + scrollback)
│   │   ├── jwt.ts        # JWT signing + verification
│   │   └── auth.ts       # Password hashing (PBKDF2)
│   └── wrangler.toml
├── docs/                 # Architecture docs
├── turbo.json            # Turborepo config
└── package.json          # Workspace root

Prerequisites

Setup

1. Clone and install

git clone https://github.com/termpod/termpod.git
cd termpod
pnpm install

2. Configure environment

cp .env.example .env

Edit .env with your values:

# Relay URL (use default or your own deployment)
VITE_RELAY_URL=wss://relay.termpod.dev

# JWT secret for the relay server
JWT_SECRET=your-random-secret-here

# Apple Developer (for code signing)
APPLE_TEAM_ID=YOUR_TEAM_ID
APPLE_SIGNING_IDENTITY=Developer ID Application: Your Name (YOUR_TEAM_ID)

# Apple notarization (only needed for distribution builds)
APPLE_ID=your-apple-id@example.com
APPLE_PASSWORD=your-app-specific-password

# Resend (for password reset emails — set via wrangler secret)
# RESEND_API_KEY=re_xxxx

# Sentry error tracking (optional)
VITE_SENTRY_DSN=
# SENTRY_DSN= (relay: wrangler secret, iOS: via generate-config.sh)

# Cloudflare TURN (optional, for WebRTC P2P across restrictive NATs)
# Create at: https://dash.cloudflare.com → Calls → TURN Keys
# TURN_KEY_ID=your-turn-key-id
# TURN_KEY_API_TOKEN=your-turn-api-token

# Tauri updater signing (must be set in shell env, NOT .env file)
# TAURI_SIGNING_PRIVATE_KEY=content-or-path-to-private-key
# TAURI_SIGNING_PRIVATE_KEY_PASSWORD=

3. Run in development

# Desktop app (dev mode, no signing needed)
pnpm dev:desktop

# Relay server (local via miniflare)
pnpm dev:relay

# Both at once
pnpm dev

4. iOS app

# Generate Xcode config from .env and regenerate .xcodeproj
pnpm ios:generate

# Open in Xcode
open apps/ios/TermPod.xcodeproj

Build and run from Xcode on a simulator or device. The APPLE_TEAM_ID from your .env is used for code signing automatically.

5. Production builds

# Desktop (sources .env for signing identity + notarization)
cd apps/desktop
pnpm build:release

# Relay (deploy to Cloudflare)
cd relay
wrangler secret put JWT_SECRET           # required
wrangler secret put RESEND_API_KEY       # for password reset emails
wrangler secret put SENTRY_DSN           # optional, error tracking
wrangler secret put TURN_KEY_ID          # optional, for TURN support
wrangler secret put TURN_KEY_API_TOKEN
wrangler deploy

Documentation

License

MIT

About

TermPod is a shared terminal app for developers. Start a session on your Mac. Run Claude Code, Codex, or any CLI tool and pick it up on your iPhone.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Contributors