webtun
v1.4.3
Published
Self-hosted web terminal with Cloudflare Tunnel, file explorer, and PWA support
Maintainers
Readme
WebTun — Self-Hosted Web Terminal
Access your Linux server from any browser — no VPN, no SSH client, no installing anything.
Why WebTun?
| Traditional SSH | WebTun | |----------------|--------| | Need SSH client installed | Open any browser | | Configure VPN or port forwarding | Cloudflare Tunnel auto-configured | | Can't access from phone easily | PWA works on iOS/Android | | Share access requires key exchange | Web-based sharing in 1 click | | Corporate firewall blocks port 22 | Runs over HTTPS (port 443) |
Features
Core
- Real shell sessions — node-pty backed, full bash/zsh support
- Multi-tab terminal — drag tabs to reorder, side-by-side sessions like your desktop
- File explorer — browse, upload, download, rename, delete, cut/copy/paste with conflict resolution (replace, merge, keep both, skip)
- WebSocket + xterm.js — responsive, low-latency typing
Mobile-First UX
- Touch gestures — swipe to close tabs, swipe from edge to open sidebar, pull-to-refresh file list
- Mobile keyboard bar — ESC, Tab, arrow keys, Ctrl combos (Ctrl+C, Ctrl+D, etc.)
- Virtual keyboard aware — terminal resizes when keyboard opens, no overlap
- Pinch-to-zoom — adjust terminal font size (10–28px) with two fingers
- Selection mode — toggle between terminal interaction and text selection
- Responsive — optimized for phones (480px), tablets (1024px), and landscape orientation
File Explorer
- Multi-select — select all / deselect all, batch delete and download files
- Zip / Extract — right-click any file or folder to zip; right-click
.zipfiles to extract - Image viewer — click images (.png, .jpg, .gif, .svg, .webp, .bmp, .ico) to preview inline
- Cut, Copy, Paste — with conflict resolution dialog (replace, merge folders, keep both, skip, cancel)
- Upload with progress — per-file progress bar via XHR
- Breadcrumb navigation — tappable directory segments for quick navigation
- Long-press context menu — rename, delete, download, copy on touch devices
- Text selection — long-press file names to select and copy text on touch devices
Desktop App (Electron)
- Cross-platform app for Linux & Windows
- Runs the server as a child process — no terminal needed
- Native window with system tray, copy/paste, and file dialogs
- Download the latest release from GitHub Releases
- Or build from source:
npm run dist:linux/npm run dist:win
PWA (Install as App)
- Add to iOS/Android home screen — looks and feels like native app
- Install banner prompts on first visit (Chrome) with iOS instructions fallback
- Works offline (shows last session state)
- Push notifications for tunnel status
Cloudflare Tunnel (Zero-Config)
- Create tunnel from UI — no CLI commands
- Built-in health check warns if local server is unreachable before creating tunnel
- Live/orphan status + target responsiveness indicator in tunnel list
- Get public HTTPS URL instantly
- Tunnels survive server restarts
- Stop/kill tunnels from settings panel
Quick Start
npm (Recommended)
npx webtunInstall globally:
npm install -g webtun
webtunOptions:
| Flag | Description |
|------|-------------|
| --port, -p | Port (default: 3000) |
| --host, -h | Host (default: 0.0.0.0) |
| --pin | Authentication PIN |
| --tunnel, -t | Start Cloudflare Tunnel |
| --help | Show help |
| --version | Show version |
Examples:
npx webtun # Start on port 3000
npx webtun --port 8080 # Custom port
npx webtun --pin secret123 # With PIN protection
npx webtun --tunnel # With Cloudflare Tunnel
npx webtun -p 4000 -t # Port 4000 + tunnelNote: npm 12+ blocks install scripts by default. Allow them for node-pty (native module):
# Allow scripts once during install
npm install -g --allow-scripts=webtun,node-pty webtun
# Or allow globally (one-time setup)
npm config set allow-scripts=webtun,node-pty --location=user
npm install -g webtunBuild tools are also required (for compiling native modules):
# Debian/Ubuntu
sudo apt-get install -y python3 make g++
# macOS
xcode-select --installOne-Command Install
bash -c "$(curl -fsSL https://raw.githubusercontent.com/unn-Known1/webtun/main/install.sh)"Manual Setup
git clone https://github.com/unn-Known1/webtun.git
cd webtun
chmod +x setup.sh && ./setup.sh
npm startGoogle Colab (Instant Terminal)
!rm -rf webtun && git clone https://github.com/unn-Known1/webtun.git && cd webtun && npm install --loglevel=error && node server.js > /tmp/webtun.log 2>&1 & sleep 4 && for i in 1 2 3; do curl -sf http://localhost:3000/api/auth/required >/dev/null && break; sleep 2; done && curl -s -X POST http://localhost:3000/api/tunnel -H 'Content-Type: application/json' -d '{"url":"http://localhost:3000"}' --max-time 20 | python3 -c "import sys,json; d=json.load(sys.stdin); print('🌐 WebTun ready at:', d.get('url','Error: '+d.get('error','')))"Architecture
┌─────────────────────────────────────────────────────────────┐
│ Your Browser │
│ ┌─────────┐ ┌──────────┐ ┌────────────┐ ┌────────────┐ │
│ │Terminal │ │ File │ │ Tunnel │ │ Settings │ │
│ │ (xterm) │ │ Explorer │ │ Manager │ │ Panel │ │
│ └────┬────┘ └────┬─────┘ └──────┬─────┘ └─────┬──────┘ │
│ │ │ │ │ │
└───────┼────────────┼───────────────┼──────────────┼─────────┘
│ WebSocket │ │ │
▼ ▼ ▼ │
┌─────────────────────────────────────────────────────────────┐
│ Node.js Server │
│ ┌────────────┐ ┌─────────────┐ ┌────────────────────┐ │
│ │ WebSocket │ │ File API │ │ Cloudflare Tunnel │ │
│ │ Handler │ │ (read/write)│ │ Manager │ │
│ └─────┬──────┘ └──────┬──────┘ └─────────┬──────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────┐ ┌────────────────┐ ┌──────────────────────┐ │
│ │ node-pty│ │Local Filesystem│ │ cloudflared daemon │ │
│ │ (shell) │ │(your server) │ │ (exposes to internet)│ │
│ └─────────┘ └────────────────┘ └──────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────┐
│ Internet Users │
│ (HTTPS URL) │
└─────────────────┘Use Cases
| Scenario | Why WebTun | |----------|------------| | Home server access | Access from anywhere without opening ports | | Emergency debugging | Phone/laptop without SSH client | | Share terminal with friend | No key exchange, just send URL | | Colab power-up | Persistent terminal alongside Python notebooks | | Demo environment | Spin up temp shell for presentations | | Corporate restrictions | HTTPS works where SSH is blocked |
Tunnel Manager
- Open Settings (gear icon)
- Go to Tunnel section
- Enter URL (default:
http://localhost:3000) - Click Create — a health check pings the target first, warns if unreachable
- Copy the public URL — share it with anyone
- View all tunnels with live status indicators (green/orange)
Note: Tunnels created before a server restart need manual cleanup:
kill $(pgrep -f 'cloudflared tunnel')Tech Stack
| Layer | Technology | |-------|------------| | Frontend | HTML + Vanilla JS (PWA, prefers-color-scheme, visualViewport, Drag & Drop) | | Backend | Node.js + node-pty + Express | | Terminal | xterm.js + fit addon | | Protocol | WebSocket (ws) | | Tunnel | Cloudflare Tunnel (cloudflared) | | Desktop | Electron + electron-builder |
Troubleshooting
| Problem | Solution |
|---------|----------|
| Tunnel URL not loading | Check Cloudflare account quota at dash.cloudflare.com |
| Permission denied on shell | Ensure user has shell access: chsh -s /bin/bash |
| File upload fails | Check public/uploads/ permissions: chmod 755 public/uploads/ |
| Port 3000 in use | Change port: PORT=3001 npm start |
Contributing
- Fork → Branch → Commit → PR
- Follow existing code style (ES6+, no frameworks)
- Test locally with
npm start - Update this README if adding features
License
MIT — do whatever you want with it.
