Skip to main content
Surge operates in three distinct modes, each optimized for different use cases. All modes share the same powerful download engine.

TUI Mode (Interactive)

The default mode provides a beautiful terminal user interface for managing downloads.

Starting TUI Mode

# Launch interactive dashboard
surge

# Start with URLs pre-queued
surge https://example.com/file1.zip https://example.com/file2.zip

# Combine URLs and batch file
surge https://example.com/file.zip --batch urls.txt
The TUI uses Bubble Tea for the interactive interface and Lipgloss for styling.

Features

Real-Time Visualization:
  • Live progress bars with chunk visualization
  • Speed graphs (current and average)
  • ETA calculations
  • Active worker count
Keyboard Controls:
  • a - Add new download
  • p - Pause/Resume selected download
  • d - Delete selected download
  • q - Quit (downloads continue in background)
  • ↑/↓ - Navigate downloads
  • tab - Switch between views
Multi-Tab Interface:
  • Active - Currently downloading
  • Completed - Finished downloads
  • Queued - Pending downloads
  • Settings - Configuration panel
Press ctrl+p while in the TUI to see all available actions and shortcuts.

Architecture

// Located in: cmd/root.go:172-250
func startTUI(port int, exitWhenDone bool, noResume bool) {
    m := tui.InitialRootModel(port, Version, GlobalService, noResume)
    p := tea.NewProgram(m, tea.WithAltScreen())
    serverProgram = p  // Save for HTTP handler
    
    // Stream events from engine to TUI
    stream, cleanup, _ := GlobalService.StreamEvents(context.Background())
    go func() {
        for msg := range stream {
            p.Send(msg)  // Convert to Bubble Tea message
        }
    }()
    
    p.Run()
}
Communication Flow:
  1. User presses key → Bubble Tea Update(msg)
  2. TUI calls GlobalService.Add(url, path, mirrors)
  3. Service queues to GlobalPool
  4. Worker emits progress → GlobalProgressCh
  5. Service broadcasts → TUI receives via p.Send(msg)
  6. TUI re-renders with new data
TUI mode also starts an HTTP server in the background on port 1700. This allows the browser extension to send downloads even when using the interactive interface.

When to Use TUI Mode

Development

Quickly test downloads and see detailed progress visualization

Manual Management

Interactively pause, resume, and monitor multiple downloads

Local Machine

You’re sitting at the computer and want visual feedback

Learning

Explore Surge’s features and settings interactively

Server Mode (Headless)

Runs Surge as a background daemon without a user interface. Perfect for servers, Raspberry Pis, or automation.

Starting Server Mode

# Start headless daemon
surge server

# Start with initial download
surge server https://example.com/large-file.zip

# Specify custom port
surge server --port 8080

# Provide explicit API token
surge server --token my-secret-token
Server mode binds to 0.0.0.0 (all interfaces) by default. This makes it accessible via localhost and your local network IP.

Features

HTTP API:
  • REST endpoints for all operations
  • Token-based authentication
  • CORS enabled for browser extensions
Headless Logging:
  • Download events printed to stdout
  • Structured logs with download IDs
  • No interactive interface overhead
Persistent Operation:
  • Runs in background (use nohup or systemd)
  • Survives SSH disconnections
  • Auto-resumes paused downloads on restart

Authentication

Server mode requires a bearer token for API access:
# Generate/view token
surge token

# Use token in API requests
curl -H "Authorization: Bearer $(surge token)" \
  http://localhost:1700/downloads
Token Storage:
  • Linux: ~/.local/state/surge/token
  • macOS: ~/Library/Application Support/surge/token
  • Windows: %LOCALAPPDATA%\surge\token
If you lose the token, delete the token file and restart Surge. A new token will be auto-generated.

Headless Output

$ surge server https://releases.ubuntu.com/22.04/ubuntu-22.04.3-desktop-amd64.iso
Started: ubuntu-22.04.3-desktop-amd64.iso [a1b2c3d4]
Completed: ubuntu-22.04.3-desktop-amd64.iso [a1b2c3d4] (in 2m34s)
Event Format:
// Located in: cmd/root.go:270-316
switch m := msg.(type) {
case events.DownloadStartedMsg:
    fmt.Printf("Started: %s [%s]\n", m.Filename, id[:8])
case events.DownloadCompleteMsg:
    fmt.Printf("Completed: %s [%s] (in %s)\n", m.Filename, id[:8], m.Elapsed)
case events.DownloadErrorMsg:
    fmt.Printf("Error: %s [%s]: %v\n", m.Filename, id[:8], m.Err)
}

CLI Commands (While Server Running)

Control the headless daemon from another terminal:
# Add download to running server
surge add https://example.com/file.zip

# List all downloads
surge ls

# Pause specific download
surge pause <download-id>

# Resume download
surge resume <download-id>

# Remove download
surge rm <download-id>
These commands automatically detect the running server on port 1700 and use the saved token for authentication.

Docker Deployment

Run Surge server in a Docker container:
# Download compose file
wget https://raw.githubusercontent.com/surge-downloader/surge/refs/heads/main/docker/compose.yml

# Start container
docker compose up -d

# Get API token
docker compose exec surge surge token

# Check downloads
docker compose exec surge surge ls
Volume Mounts:
  • /downloads - Download destination
  • /config - Surge configuration and state

When to Use Server Mode

Servers

Run on headless Linux servers without X11/GUI

Automation

Integrate with scripts, cron jobs, or orchestration tools

Remote Access

Access downloads from anywhere via HTTP API

Low Resources

Minimal memory/CPU usage without TUI rendering

Remote TUI Mode (Connect)

Connect a TUI to a remote Surge server. Provides the interactive interface while downloads run on a different machine.

Connecting to Remote Server

# Auto-detect local server
surge connect

# Connect to specific host
surge connect 192.168.1.10:1700 --token <token>

# Connect to public server (uses HTTPS)
surge connect surge.example.com:1700 --token <token>

# Alternative syntax (global flags)
surge --host 192.168.1.10:1700 --token <token>
Surge automatically uses http:// for loopback/private IPs and https:// for public/hostname targets.

Architecture

// Located in: cmd/connect.go
func connectAndRunTUI(cmd *cobra.Command, hostTarget string) {
    // Create remote service wrapper
    remoteService := core.NewRemoteDownloadService(hostTarget, token)
    
    // Initialize TUI with remote backend
    m := tui.InitialRootModel(port, Version, remoteService, noResume)
    m.IsRemote = true
    
    // Stream events via HTTP
    stream, cleanup, _ := remoteService.StreamEvents(context.Background())
    go func() {
        for msg := range stream {
            p.Send(msg)
        }
    }()
}
Key Differences from Local TUI:
  • Commands sent via HTTP POST instead of direct function calls
  • Events streamed via Server-Sent Events (SSE) or polling
  • Network latency affects responsiveness
  • Uses RemoteDownloadService wrapper instead of LocalDownloadService

Environment Variables

Avoid typing host/token repeatedly:
# Set in shell profile
export SURGE_HOST=192.168.1.10:1700
export SURGE_TOKEN=abc123-def456-ghi789

# Now just run
surge connect

When to Use Remote TUI

NAS/Home Server

Downloads run on NAS, control from laptop

Cloud VM

Manage downloads on AWS/GCP from local terminal

SSH Alternative

Use local TUI instead of SSH + screen/tmux

Multiple Clients

Multiple developers controlling shared download server

Mode Comparison

FeatureTUI ModeServer ModeRemote TUI
Visual Interface✅ Yes❌ No✅ Yes
HTTP API✅ Yes (background)✅ Yes✅ Yes (client)
Headless❌ No✅ Yes❌ No
Remote ControlVia APIVia API/CLINative
Resource UsageMediumLowLow (server) + Medium (client)
Auto-Resume✅ Yes✅ Yes✅ Yes
Browser Extension✅ Yes✅ Yes✅ Yes (server-side)
Event StreamingIn-processStdoutHTTP SSE/polling
Yes! You can:
  1. Start in TUI, quit, resume in Server:
    surge              # Start TUI
    # Press 'q' to quit
    surge server       # Resume in headless mode
    
  2. Start in Server, connect with Remote TUI:
    surge server       # On server machine
    surge connect      # On client machine
    
  3. Use CLI commands with any mode:
    surge server &     # Background server
    surge add URL      # Add via CLI
    surge ls           # Check status
    
Downloads persist across mode changes because they’re managed by the shared GlobalPool and SQLite database.

Choosing the Right Mode

For most users, TUI Mode is the best starting point. Once you’re comfortable, explore Server Mode for automation and Remote TUI for managing downloads on other machines.