┌──────────────────────────────────────────────┐
│ ● S E R V E R B R D G │
│ SSH File Manager for your Mac │
└──────────────────────────────────────────────┘
Browse and download files from any SSH server — right in your browser.
ServerBridge is a local desktop web app that turns any SSH server into a browsable file system. One command starts a Bun server on your Mac, opens a browser tab, and gives you a dual-pane file manager — your server on the left, your Mac on the right. Select files, click Download, watch the progress bar fill.
No Electron. No cloud. No accounts. Just SSH, rsync, and a browser tab.
Connect screen — saved connections, SSH key auto-detection, password fallback
File manager — dual-pane with live transfer progress
SSH terminal — multiple tabs, snippets panel, session logging
Port forwarding — local tunnel management
File management
- Dual-pane file manager — server on the left, your machine on the right, both fully navigable
- Download — select any file or directory, click Download; progress bar with speed and ETA
- Upload — drag files onto the remote pane, or use the Upload button; streams via SFTP
- Smart directory transfers — with Compress ON, directories are tarred on the server, transferred as a single archive, then extracted locally — far faster than rsync-ing thousands of small files
- Download to current location — wherever you navigate in the right pane is where files land
- Cancel mid-transfer — kills the rsync process and cleans up the remote temp archive
- rsync with SFTP fallback — works on Windows and any host where rsync isn't available
SSH terminal
- Full interactive shell — xterm.js PTY in the browser, with ANSI color and resize support
- Multiple tabs — open as many terminal sessions as needed, each independent
- Snippets — save, name, and run shell commands with one click; stored in
~/.serverbrdg.json - Session logging — save terminal output to a local
.txtfile
Connections
- SSH key + password auth — auto-detects
~/.ssh/id_rsa,id_ed25519,id_ecdsa; or supply a path or password - Saved connections — one-click reconnect (passwords never stored)
- Session persistence — reloading the browser tab reconnects to the existing SSH session automatically
- Port forwarding — create local TCP tunnels through the SSH connection; manage from the Tunnels tab
General
- Navigate freely — breadcrumb paths, double-click to enter folders,
..to go up - Live progress — real-time percent, transfer speed, and ETA over WebSocket
- Auto-refresh — local pane updates as soon as a transfer completes
- WebSocket reconnect — browser reconnects automatically if the server restarts
Requirements: Bun · SSH access to your server · rsync recommended (optional — SFTP fallback kicks in automatically)
git clone https://github.com/Robinbinu/serverbrdg
cd serverbrdg
./start.shA browser tab opens at http://localhost:3847.
git clone https://github.com/Robinbinu/serverbrdg
cd serverbrdg
start.batThen open http://localhost:3847 manually. On Windows, transfers use SFTP automatically (rsync not required).
Your Mac
└── Bun server (port 3847)
├── HTTP → serves index.html
├── REST → SSH connect/disconnect, SFTP browse, transfers, upload, snippets, tunnels
├── WS /ws → real-time transfer progress
└── WS /ws/terminal → interactive PTY shell (xterm.js ↔ ssh2.shell)
Browser (vanilla JS, no framework)
├── Connect screen → POST /api/connect
├── Files tab → GET /api/browse/remote · GET /api/browse/local
│ ├── Download → POST /api/transfer → rsync / compress flow
│ └── Upload → POST /api/upload → SFTP createWriteStream
├── Terminal tab → WS /ws/terminal → full PTY via ssh2.shell()
└── Tunnels tab → POST /api/forwards → net.createServer + sshClient.forwardOut
| Item type | Compress toggle | Method |
|---|---|---|
| Single file | — | rsync direct, or SFTP if rsync unavailable |
| Directory | ON | SSH tar -czf → rsync/SFTP archive → local tar -xzf → cleanup |
| Directory | OFF | rsync -avz recursive, or recursive SFTP |
| Layer | Choice | Why |
|---|---|---|
| Runtime | Bun | Single binary, built-in HTTP+WebSocket server, fast startup |
| SSH | ssh2 | Pure-JS SSH2 client, SFTP support, Bun-compatible |
| Transfer | rsync (system) | Battle-tested, restartable, native progress output |
| Frontend | Vanilla JS | No build step, no dependencies, instant reload |
| Fonts | JetBrains Mono | Google Fonts |
serverbrdg/
├── server.ts ← Bun HTTP + WebSocket server, all backend logic
├── server.test.ts ← Unit tests (bun test)
├── public/
│ └── index.html ← Full SPA — connect screen, dual pane, transfer queue
├── package.json
├── start.sh ← macOS/Linux: bun install → start server → open browser
└── start.bat ← Windows equivalent
Nothing to configure. Defaults that matter:
| Setting | Value |
|---|---|
| Port | 3847 |
| SSH port | 22 (overridable in the UI) |
| Default key paths | ~/.ssh/id_rsa, ~/.ssh/id_ed25519, ~/.ssh/id_ecdsa |
| Download destination | wherever you navigate in the right (local) pane |
| Saved connections | ~/.serverbrdg.json (passwords never stored) |
bun test✓ formatBytes: zero returns dash
✓ formatBytes: kilobytes
✓ formatBytes: gigabytes
✓ parseRsyncProgress: valid progress line
✓ parseRsyncProgress: non-progress line returns null
✓ parseRsyncProgress: kilobytes speed
✓ Desktop directory exists
7 pass, 0 fail
- One server at a time — single SSH connection per session
- tar required — directory compression needs
taron the remote server (available on all Linux/macOS servers)
Issues and PRs welcome. The codebase is intentionally small:
- Backend logic lives entirely in
server.ts(~580 lines) - Frontend lives entirely in
public/index.html(~800 lines) - No build step — edit and reload
MIT



