WebTun
USER GUIDE

Your terminal, everywhere.

WebTun puts a full shell, a code editor, your files and git — behind one PIN, in any browser. This guide walks through everything the app can do, so no feature stays hidden. About 5 min cover to cover.

15 chapters 15 shortcuts Works  offline as PWA

Popular topics

60-second tour #

Brand new? Do these five things and you'll know 80% of the app.

Start the server & unlock. Run it, then enter your PIN — first run has none, so set one in Settings → Security. Everything sits behind it.

Open a second terminal tab with Ctrl+T. Tabs keep running when you switch, refresh, or briefly lose connection.

Press Ctrl+P to fuzzy-find any file, and Ctrl+B to toggle the file explorer sidebar.

Create a tunnel from Settings → Tunnel to get a public HTTPS URL for your phone or a friend's laptop. How it works.

Install it as an app from your browser menu — it works offline as a PWA and reconnects automatically.

Run the server #

WebTun is one process — start it on any machine and the whole guide above comes alive in a browser.

First time: run ./setup.sh — it installs Node 18+, project dependencies and the tunnel connector.

Every day: npm start, then open http://localhost:3000. Stop it with ./stop.sh.

Set a PIN immediately in Settings → Security — an empty PIN means anyone on your network can walk in.

CLI flags #

FlagDoes
--port -pListen port (default 3000)
--host -hBind address (default all interfaces)
--pinPIN for this run
--tunnel -tStart with a public tunnel URL
--update --upgradeCheck for updates and upgrade package directly
bash
webtun --port 8080 --tunnel
# server on :8080, reachable worldwide via HTTPS

Upgrade WebTun #

Upgrade your WebTun package directly from the terminal whenever a new version is published:

CommandDoes
webtun update (or upgrade)Check the npm registry and upgrade package directly to the latest version
webtun update --checkCheck whether a newer version is available without installing
webtun update --forceForce reinstall or upgrade even if already on the latest release
webtun update --globalForce global package upgrade via npm (npm install -g)
webtun update --tag <tag>Upgrade to a specific npm dist-tag or version (e.g. next)
webtun update --dry-runShow the simulated upgrade command without making changes
bash
webtun update
# Checks npm registry and upgrades WebTun directly

Configure with .env #

Same knobs, persisted. The file lives next to the server (or ~/.config/webtun/.env for global installs) alongside history and tunnel memory.

env
PORT=3000
# Bind locally only. Put comments on separate lines.
HOST=127.0.0.1
# Empty PIN disables protection; use a strong PIN for remote access.
PIN=pick-a-strong-one
# Use an absolute path; .env does not expand ~ or shell variables.
WORKSPACE_ROOT=/home/you/projects

The file browser starts at WORKSPACE_ROOT. Explicit environment values take priority over both .env locations, including PREVIEW_PORTS. Set ALLOW_FULL_FS=false to confine the File API; terminal shells remain unconfined.

Watch the host #

The overflow menu → System Stats opens a live dashboard: CPU, memory, disk, uptime — and GPU cards with VRAM, utilization and temperature where detectors exist — alongside Network Interfaces & DNS (active interfaces with click-to-copy IP/CIDR addresses, MAC, RX/TX traffic counters, default gateway, DNS resolvers, and listening port counts) plus the top processes by CPU, with a Kill button per row for runaways. Filter processes by PID, user or command, and select a column heading to sort in either direction. On phones, swipe the process table horizontally to reach every column and the Kill controls; the metric cards stay in a compact two-column layout. The footer shows the last update, with Refresh for an immediate update. It polls every five seconds and politely pauses when the tab is hidden or Data Saver is on.

Home base #

No tabs open? You don't get an empty screen — you get the Launchpad. The Home button pinned left of the tab bar brings it back any time.

  • Start with New terminal. The three shortcuts below it open Sessions, Explorer, and Snippets. SSH access is in the header menu or Settings → SSH Access.
  • Recent commands, one key away. Your greatest hits are listed as cards — click one, or just press 1–6 to launch-and-run it in a fresh tab.
  • Places jump you to favorite folders instantly; the Today strip keeps the current context in sight.
  • Live system pulse — a sparkline of host load right on the dashboard, so you know before you SSH in whether the box is sweating.
  • Prefer a blank slate? The Home button is pinned left of the tab bar, so the Launchpad is always one click away — open a tab and it steps aside on its own.

Terminal #

A real shell in every tab — not a simulation. Full filesystem access, your own shell, links you can click.

  • Tabs for everything — Ctrl+T opens one, Ctrl+W closes it, Ctrl+Shift+→/← cycles. The + button follows the last tab on desktop and mobile and stays visible when the tab strip needs scrolling. Double-click a tab to rename it, and your whole tab layout (terminals, app previews and open files) is remembered across reloads. The tab strip is keyboard reachable too: Tab onto the active tab, then ←/→ to move (or Home/End for the ends), and in tile view each tile header is focusable and activates with Enter.
  • Jump directly with Alt+1…8 (Alt+9 always lands on the last tab), rename with F2, duplicate the current terminal in its working directory with Ctrl+Shift+D, and reopen an accidentally closed tab with Ctrl+Shift+T (a fresh shell in the same directory — scrollback can't be restored). Middle-click closes any tab (pinned tabs ask first).
  • Notification center — every toast is also kept in the bell panel (header, left of Settings) until you clear it: per-item dismiss, swipe-to-dismiss on touch, plus Clear all, newest first, with the badge counting what arrived while it was closed. The log survives reloads, so history from before a refresh is still there. Toasts carry their own × close button, errors stick around longer (and are never pushed out by info bursts), and hovering a toast pauses its auto-dismiss.
  • Right-click any tab for the full menu: Rename, Duplicate, a 7-color tag (green for the API server, red for prod-ssh…), Pin, Clear Buffer, Restart Session, Close, Close Others, Close Tabs to the Right. Colors and pins survive reloads; pinned tabs keep their titles (with a pin marker and amber underline), group left, are skipped by bulk-close, and ask first before any single close (×, middle-click, Ctrl+W included) — pin with Ctrl+Shift+P, and a reopened pinned tab comes back pinned. Right-click the + button (or empty tab-bar space) for New Terminal / Duplicate / New Preview / Tile View.
  • Background tabs speak up. Output in a tab you're not looking at raises a green activity dot, a terminal bell raises an amber badge, and an exited process dims the tab with a red marker — all cleared the moment you visit. When the strip overflows, arrow buttons scroll it and the ⌄ switcher lists every tab with a live filter. On mobile, tap Tabs in the bottom navigation to open that list, filter and select a tab; tap the backdrop to dismiss it.
  • A consistent tab bar on desktop and mobile. The active tab has a top accent line, and a pinned tab keeps its amber underline even when active. Scroll arrows appear only when there are more tabs in that direction; the +, preview and SSH controls stay outside the scrolling tab list. Mobile keeps the same rounded-top tab shape with taller touch controls and snaps to whole tab slots, showing one or two tabs depending on available space. Long hostnames in the header end with an ellipsis; the host button still opens SSH & connections.
  • New shells start at the top. If shell startup leaves only empty rows above the first prompt, WebTun asks the shell to redraw it at the top. Startup messages and restored sessions keep their position, and typing cancels the startup redraw.
  • Connection recovery is bounded. Network failures retry with increasing delays. If reattachment keeps failing, WebTun tries one fresh session, then stops automatic retries and offers Reconnect. If the terminal's native connection becomes unavailable, WebTun closes the broken connection and uses the same recovery flow; an in-memory shell that has stopped cannot retain its running commands. A refused or revoked login stops retries immediately; sign in again when prompted.
  • Sessions survive accidents. Refresh the page, close the laptop, drop Wi-Fi — your shells keep running server-side (via tmux when available) and reattach exactly where you left them. List & connect to all terminal sessions — both WebTun tabs and external terminal sessions (tmux sessions started via SSH, scripts, or CLI) — directly from the Launchpad, the Sessions button (Alt+S), Quick Search (⌘K), or the header menu. Filter by All, WebTun, or External, search live across session names and directories, customize session labels, attach seamlessly into live interactive tabs, and manage them on both desktop and mobile with touch-optimized responsive controls.
  • The Terminal Sessions browser keeps search and the All / WebTun / External filters visible above its scrolling list. Session names, directories and commands wrap for readability. Use Label to rename a session, Connect to attach, Switch to Tab for an already-open session, or Open Shell for a detected external process. Terminate still asks for confirmation. On phones, the connection action gets its own full-width row, with Label and Terminate below. The footer shows how many sessions match; the list updates every four seconds while open, retaining your scroll position.
  • Tile view lays every terminal out in a grid at once — and every open code file with it, so you can watch two logs and edit three files in one screen. Each tile shows a live connection dot (disconnected red, unsaved-changes amber, connected green), pin/color/activity/bell/exit markers, a Maximize (⤢) toggle, and a ⋯ menu (Rename, Restart session, Clear buffer, Close others) to temporarily focus a single pane. Toggle with Alt+G or the overflow menu, move between tiles with ←/→ on a focused tile header, drag a tile header to reorder it, restore a maximized tile with Esc, and pin the column count (Auto / 1 / 2 / 3 / 4) from the Columns row in the overflow menu. Broadcast Input can skip individual terminals via a tile's ⋯ menu, and code tiles merge their title bar into the editor toolbar to save space. Tile View, columns, exclusions, and the maximized tile are remembered across reloads.
  • Broadcast Input lets you type into every open terminal tab simultaneously — toggle it from the tab bar or overflow menu when running cluster-wide maintenance.
  • Search inside output with Ctrl+F (match highlighting, optional case-sensitivity), and click file paths & URLs printed by your tools to jump straight there.
  • Scroll output and TUI apps with your mouse wheel or a touch swipe. Repeated swipes scroll without triggering double-tap text selection. Scrollback keeps trackpad movement smooth; alternate-screen apps receive wheel navigation or mouse-wheel events according to their terminal mode. In a shell, the keyboard up/down arrows remain available for command history; selection mode has separate Scroll up/down buttons for moving through output.
  • Confirm on Close guards tab closes (on by default) — and warns about unsaved editor changes before a tab disappears.
  • Commands are remembered. What you type is tracked (escape sequences filtered out), so the command library and history stay clean and reusable.
  • Clipboard access is opt-in. Programs can always copy to your clipboard, but reading it (OSC 52 paste, used by terminal editors) is off by default — otherwise stray output could quietly pull your clipboard into the session. Turn on Settings → Terminal → Allow terminal clipboard read when you want it.
  • TUI shortcuts & Ctrl+K passthrough. By default, Ctrl+K opens Quick Search. When using TUI apps (such as nano, micro, fzf, lazygit, or shell line-kill), turn on Settings → Terminal → Pass Ctrl+K to terminal to send Ctrl+K straight to your running program (Quick Search then opens with Ctrl+Shift+K). Even with the setting off, you can send Ctrl+K to your TUI anytime via Ctrl+Shift+K, right-click → Send Ctrl+K, or the mobile ^Row toolbar.

Tip: long-running job? Start it in its own tab. Even if the browser tab closes, the process keeps going on the host.

Editor & previews #

Click any text file to edit it with highlighting for JS, Python, HTML, CSS, Shell, YAML, SQL, Go, Rust, Markdown and more.

  • Save with Ctrl+S, search with Ctrl+F. A dot on the file name marks unsaved changes, the toolbar shows your live Ln X, Col Y cursor position, and the built-in Find / Replace / Go-to-Line bar (Ctrl+F / Ctrl+H / Ctrl+G) supports case-sensitive and regex matching in both the split panel and file tabs. Toggle Word Wrap in the editor header or configure Tab Size (`2`–`8`) in Settings → Appearance.
  • Live Log Tail (`tail -f`). Opening any .log, .out, .err, or .txt file reveals a Live Tail button that streams appended lines in real time with Pause/Resume and Clear controls.
  • Live preview for HTML and Markdown in a sandboxed pane — Ctrl+Shift+R refreshes it. HTML preview has two modes: Safe (default — scripts stripped) and Full via the Full button, which runs the file's own scripts in the same isolated frame: no access to the app, its storage, or your files. Preview file assets load with short-lived scoped tokens, never your session token. The markdown parser and HTML sanitizer ship with WebTun, so text previews work with no internet connection.
  • Office & CSV/TSV files open read-only right in the app: Word (.docx) renders with text, tables and embedded images; Excel (.xlsx) and .csv/.tsv files get an interactive spreadsheet grid with live row filtering, sheet switching, column letters, row numbers, merged cells, and sticky headers. Legacy .doc/.xls/.ppt? The app tells you to re-save rather than showing garbage.
  • PDFs and ebooks too. PDFs render with a selectable text layer (search and copy work); EPUBs open as a proper paged reader.
  • Work it your way: F11 takes the editor fullscreen, the split toggle flips code/preview between side-by-side and stacked, and unsaved edits are auto-drafted — crash mid-sentence and your words are still there. Re-open the file and WebTun asks whether to restore the draft or discard it (drafts are only offered when they differ from what's on disk, and are cleared once you save or explicitly discard).
  • External changes sync themselves. If the file changes on disk while you have it open (another program, a teammate, your own terminal), WebTun notices within seconds: with no unsaved edits the buffer reloads automatically and says Updated from disk. With unsaved edits your words are never touched — instead a cyan dot plus a Changed on disk note appears in the toolbar (and a marker on the tab). Click the note to reload from disk — it asks before discarding your edits — or press Save to keep your version and overwrite. A file deleted out from under you is flagged the same way, and if it comes back the note flips to Changed. PDF, ebook and Office tabs are watched too (flag-only, never auto-reloaded), while files that grew past the open size guard raise the flag instead of reloading. The note is keyboard-operable (Enter/Space) and announced to screen readers.
  • Images preview inline (PNG, JPEG, GIF, SVG, WebP, AVIF, BMP, ICO) instead of downloading. Big binaries stay out of the editor. Truly unsupported files say so plainly instead of showing garbage.

File tabs #

The tab button in the editor header — or Open in Tab in a file's right-click menu — moves the open file off the split and into the tab strip beside your terminals, so a source file, a README, a PDF and a preview can all stay open at once.

  • Every code file gets its own live editor — that is what makes tabs worth it. Switch to Tile view and three, four, five files render side by side, each with its own cursor, scroll position and undo history. Nothing is torn down on a switch, so your edits and place survive.
  • Each tab carries its own toolbar: Save (Ctrl+S), Reload to discard edits and re-read the file from disk, and Panel to hand the file — buffer and undo history included — to the split editor when you want fullscreen or the split layout. Markdown and HTML tabs also get Preview (plus Full for HTML scripts) with live re-render as you type. An amber dot marks unsaved changes, and the tab itself gets a dot too. A cyan Changed on disk marker means the file moved underneath you while you had edits — click it to reload, Save to overwrite.
  • Switch, rename, close, reorder — file tabs are ordinary tabs: click, Ctrl+W, drag, double-click to rename. Dragging onto the left or right half of a tab drops before or after it. Up to 10 file tabs at once; opening a file that already has a tab focuses it instead of duplicating, and unsaved work is auto-drafted and offered again after a crash, exactly like the editor panel.
  • One heavy document at a time. PDF, EPUB and Office tabs share a single viewer — they hold whole documents in memory, so a pile of them would be expensive. Switching away parks the previous one behind an Open card, and activating it again restores your page, zoom, sheet and scroll position.

App preview tabs #

Running a dev server? Open a New Preview from the overflow menu (or the toolbar button), type its port — say 5173 — and your app renders in a tab right beside the code. Edit path, refresh, open it in a new tab, or copy a shareable preview URL from the toolbar.

  • Zero setup: when your terminal prints localhost:5173, a toast offers to open it right away; the port field also autocompletes detected listeners (with process names) plus your recent ports. You can paste a full localhost:5173/docs URL into the port or path field. Any port 1–65535 works — single-digit dev ports and 80/443 included — and paths with ? & # are encoded safely.
  • Back/forward, live address bar, status dot: the toolbar follows in-page navigation, the dot shows whether the app is answering (click to retry), and a dead-then-restarted dev server reloads itself automatically.
  • Auto-reload on save, width presets, recent ports: tick Auto to refresh the preview when you save a file, narrow the frame to 375/768px to eyeball mobile layouts, and reopen where you left off — port, path and recent ports survive reloads.
  • Streams and downloads proxy through; dev-server WebSocket channels (hot-reload sockets) do not — the proxy is HTTP-only, so refresh the tab to see changes. Slow first boots get a 30s cold-start budget, and only page navigations skip compression so assets stay gzipped.
  • Actionable errors: a dead preview names the cause (bad port, allow-list block, nothing listening, slow start) with the curl 127.0.0.1:PORT check and a Retry button.

Copied preview links carry your access token. Anyone opening one browses as you — share them like passwords, never publicly.

Preview access belongs to a device, not its IP. The first navigation exchanges your login for a short-lived, single-port capability and HttpOnly cookie. Each request rechecks the issuing session; sign-out/revocation invalidates it. WebTun credentials are removed from both HTTP and HMR WebSocket upstream URLs, while app-owned ?token= values pass through. Raw-PIN access keeps the normal approval gate. Back/Forward buttons use frame-side history commands without weakening the sandbox.

Server admins can narrow previews to specific ports with PREVIEW_PORTS=5173,8080 in .env — useful when the box runs databases or admin panels whose ports you would rather not expose through your session. Unset (the default) allows any port except WebTun's own.

Two honest limits: previewed pages run storage-less by design (localStorage/JS cookies unavailable, so token-based logins won't stick), and apps that hardcode absolute localhost URLs or OAuth callbacks may misbehave — especially over a remote tunnel. The sandbox is enforced by the server, not just by the frame, so a previewed app can never reach your session token or files — even if you open its preview URL directly in a new tab.

deploy-notes.md — preview sandboxed
## Ship checklist + tunnel URL copied to runbook + PIN changed after demo .restart policy set to always
Markdown preview renders instantly beside the editor — no build step.

Keep edits safe #

  • Keep typing while a save runs. Save writes the version you submitted. Edits made while it is pending remain marked unsaved and keep their recovery draft; save again to write them.
  • Move a file without losing your place. Panel and tab views keep the same edits, dirty marker, and undo history. Opening a different file starts its own undo history. When you leave an edited panel file, Keep draft and open preserves its recovery draft.
  • Late disk reads preserve newer edits. If you type while a reload is pending, your text stays in place and Changed on disk remains visible. Review the disk version when ready.
  • Editing still works if the editor library cannot load. A plain text area supports edits, saves, drafts, and moving files between panel and tab. Syntax highlighting returns when the library is available.

Unexpected action failures show an error toast and stay in the Notification center.

Safe file & session operations #

  • Recovery drafts stay recoverable. Restoring a draft keeps its saved recovery copy until you save or explicitly discard it. A background text tile with a recovery draft stays read-only until you activate it and choose Restore or Discard. Closing it before review keeps the draft for next time.
  • Switching files keeps Save pointed at the displayed text. Syntax modes may finish loading later; edits and saves made during that wait belong to the newly opened file.
  • Copy/move protects nested sources. A folder cannot replace a parent that contains it. Skip applies only to existing destinations; other selected files still transfer.
  • Git selections use literal filenames. Characters such as brackets and asterisks do not select other files. Unstage works before the first commit and handles both sides of a staged rename. Individual hunks can be staged or unstaged independently.
  • Sign-in happens before license loading. Reload resumes a valid session before checking limits and restoring tabs. A temporarily unavailable license status does not shorten your saved workspace. Mistyping the current PIN during a PIN change shows a validation error and keeps you signed in.
  • Startup and tunnel failures are reported. The desktop app starts its local server before opening the window. Windows CLI upgrades invoke npm through Node. A tunnel that exits during its readiness check is reported as failed so you can retry.

Recovery & operation limits #

  • Exit means exit. A normally ended shell stays ended. Use the tab menu → Restart Session for a new shell. Automatic recovery is for network/native-connection failures, not an intentional exit.
  • Pinch stays local. Touch zoom changes the current terminal between 10–28 px without changing saved settings for new tabs. Interrupted gestures reset. The optional Python PTY fallback forwards window-size changes; the pipe-only fallback has reduced interactive/TUI support.
  • Signing out keeps drafts. Revocation closes dialogs, polling and editors, releases file ownership and returns to the PIN screen. Reopen after sign-in to restore unsaved text. Late unauthorized responses do not erase a PIN you are typing.
  • Folder renames follow open descendants. Editor paths and drafts move together. Renames wait for saves and refuse occupied destinations; saving cannot run halfway through a rename.
  • Previews show the latest completed revision. Late HTML/Markdown rendering cannot replace newer content. Failed file-asset authorization shows an unavailable message rather than substituting your session secret. PDF, EPUB and Office toolbar downloads use the displayed file in either panel or tab.
  • Every upload owns its Stop control. Stopping one job leaves another alone. Small-file batches wait and retry the server's rate-limit budget. The server creates validated subdirectories from multipart filenames, up to 10 folder levels.
  • ZIP limits match in both directions. Create/extract up to 50,000 entries and 1 GB; encrypted and ZIP64 archives remain unsupported. Corrupt streams reject promptly. Failed merges restore entire backed-up subtrees; if the filesystem also refuses rollback, the server log identifies a retained recovery backup.
  • Link metadata and file contents are separate. Properties describe the selected symlink, including broken links; editors watch the resolved file. Single-file download APIs support byte-range responses (206/416). Generated directory ZIP streams are not resumable.
  • Background work is bounded. Data Saver and hidden-page checks pause automatic system polling in the header, stats and Launchpad. Keep-awake fallback streams and notification audio resources are released when inactive/complete. Regex search runs in a time-limited worker; simplify a timed-out pattern or use literal search. The log-tail API emits reset events on rotation/truncation.
  • Persistence is not a transaction guarantee. Runtime configuration/labels use atomic state writes. Editor document saves are ordinary filesystem writes, not crash-proof atomic replacements; keep backups for valuable files.

File manager #

Browse the whole host filesystem, or stay inside your workspace. Right-click anything for the full action menu.

Move & organize

Rename, copy, cut, paste, delete, new file/folder. Clashes offer replace, merge, skip, or keep-both.

Upload & download

Drag-and-drop upload (up to 500 MB × 100 files), download single files or whole folders as a zip.

Zip in place

Zip (stored, uncompressed) and extract archives without touching the terminal.

Instant search

Find files by name from the search box — capped for speed on giant trees.

  • A compact explorer on every screen. Navigation, content search, Select mode and Refresh share one toolbar, with Refresh beside Select mode. Toggle the explorer from the sidebar button or with Ctrl+B. The current path and bottom file-action toolbar stay available while the explorer body scrolls on short screens. On phones, a wider drawer and compact file rows leave more room for names, with download and more-actions controls always visible. On narrow desktop sidebars, the toolbar scrolls horizontally instead of clipping its tools.
  • Navigate folders with Back, Forward and Go up, or enter a path directly. Type-ahead, arrow keys and select-all all work in the list.
  • See your full directory path. A single path display wraps across the explorer width and shows up to 120 characters in full. Longer paths truncate in the middle, keeping the beginning and end visible. Hover to see the complete path, or click it or the pencil to open the editable field with the entire path selected for copying or navigation.
  • Bookmark favorite folders. Star the current directory and it joins the bookmarks list under the explorer (synced server-side across your devices): hover to peek, click (or Enter) to pin it open, and jump back any time with one click. The count badge and open/closed state survive reloads.
  • Long names truncate in the middle so the extension stays visible (very-long-file…name.js); select a row or focus it with the arrow keys to reveal the complete name.
  • Batch with Select mode. Flip the select toggle and checkboxes appear — tick a dozen files, then delete, download, zip, cut or copy them in one move. The selection toolbar stays available even with nothing selected; Delete and Download become available after selecting items. Cancel exits Select mode.
  • Archives, symlinks, media & live log tailing. Right-click any item to compress as .zip or .tar.gz, extract .zip/.tar.gz/.tgz/.tar archives, create symbolic links, stream .mp4/.webm/.mp3/.wav media with byte-range seeking, or open a live SSE log tail (Tail Log (Live)) with pause and auto-scroll.
  • Right-click → Folder Size reveals what's eating your disk before you reach for du.
  • Search inside files with the magnifier in the explorer header: literal or regex full-text search across the current folder (depth-capped, binaries skipped) — click a hit to open it.
  • Right-click → Properties shows size, dates, owner and permissions, and lets you chmod real files and folders (octal, e.g. 755).
  • Uploads keep their shape. Dropping a folder preserves its subfolders, and international filenames (accents, CJK, Cyrillic, spaces) arrive intact instead of flattened underscores.
  • Clipboard travels with you. Copy/cut is mirrored server-side, so a refresh, a second tab or a re-login keeps it — and pasting with an empty tab restores it automatically.
  • Conflicts, your way. Batch pastes can apply one choice to every remaining collision, and Cancel stops the whole batch instead of failing one file at a time. Extracting over an existing folder lands in a numbered sibling (archive (1)/).
  • Renames follow open files. Renaming a file updates the editor panel, its tabs and any unsaved draft — saving afterwards writes the new path, never resurrects the old one. Deleting a symlink removes the link, never its target.
  • Big downloads behave. Multi-file downloads arrive as one combined zip (no popup-blocked stragglers), and large files stream straight to disk where the browser allows instead of filling the tab's memory.
  • Transfers panel. The up/down icon next to the coffee cup shows live uploads, downloads and copy/move jobs with speed and time left — hover to peek, click to pin. Copy/move pause while a conflict dialog waits for you, and Stop halts uploads/downloads at once or copy/move after the current file.
~/projects 4 items
webtunGIT
notes.mdEDIT
demo.mp412 MB
cover.pngVIEW
Badges tell you at a glance what's editable, viewable, or version-controlled.

Git panel #

Open any repository folder and the Git panel lights up — stage, review, commit, sync without memorizing flags.

  • Stage by hunk, not by file. Split a diff into pieces and stage exactly the lines you mean — perfect for untangling mixed-up edits. The button is pinned to the hunk you clicked, so if the file changes underneath you between opening the list and clicking, you get a refresh and retry instead of the wrong lines being staged.
  • Read before you commit: per-file diffs, commit history with detail view, branch & tag management, stash and pop. Click any changed-file row to open its diff (the first change is pre-selected).
  • Author identity per repo. The panel asks for your name and email once per repository — commits simply refuse to run until it's set.
  • Sync safely: pull (merge, rebase or fast-forward-only), push with upstream setup, fetch with generous timeouts for slow networks.
  • Simple mode for a calm panel (on by default): the Git panel hides its rarely-used actions (amend, fetch, refresh, stash, reset, tags) — a Show advanced… button at the panel bottom reveals them in place. Prefer everything visible? Switch it off in Settings → Features.
  • Escape hatches included: amend the last commit, soft/mixed/hard reset to any commit, discard files, init a fresh repo.
  • Conflicted files can be finished here. Unmerged paths offer Diff (against HEAD), Stage once you've resolved the markers in the editor, and per-file Hunks — and opening a conflicted file in the editor reveals a 1-click Accept Ours / Accept Theirs / Accept Both conflict bar.
  • Per-file Git History. Click the History button in the editor header (or on any file tab) to inspect every commit that touched that file along with its per-commit diff.
  • Advanced branch workflows. In Show advanced…, enter a local branch to merge into the current one or delete. Deletion refuses unmerged work unless you explicitly allow it and confirm. Active merges/rebases expose Continue after resolving/staging, or Abort with a discard warning.
  • Read older history and blame. Older/Newer commits page through bounded history lists. Blame shows 200 lines at a time for a repository-relative text file up to 2 MB; the next-line field advances after each view. Unicode names, quoted names and rename pairs retain their actual paths.
server.js — 2 hunks +18 −4
@@ -210,7 +210,9 @@ rate limiter - windowMs: 10 * 1000, max: 5 + windowMs: 10 * 1000, max: 5, + message: 'Too many attempts'
Stage this hunk, leave the rest — one click per hunk.

History & command library #

Stop retyping that deploy incantation. WebTun collects what you run and lets you organize, save, and reuse snippets with one click.

  • Automatic history — every command you run is saved (terminal escape noise filtered out), indexed by recency and run count, searchable, and deletable one-by-one or in full.
  • Save to Library from History — click the star icon () on any history entry to immediately save it to your reusable snippet library.
  • Quick Actions & Parameterized Snippets — Run (execute in terminal), Paste (insert into active buffer without auto-running), Copy (one-click copy to clipboard), Edit, and Delete. Any command containing {{var=default}} or <placeholder> tokens automatically opens a parameter prompt with a live command preview before running or pasting.
  • Category chips & smart filter — filter presets across AI Tools, CLI Tools, Git, System, Network, Docker, Node & Dev, and Custom. Search matches names, syntax, and categories simultaneously.
  • Browse comfortably on desktop and mobile. Commands wrap so their full syntax stays readable, and the Run action is labeled separately from Paste and Copy. On phones, actions sit beneath each command and categories scroll horizontally. Expand Save a command to add a snippet with a label and category; Edit opens that same form automatically. Use arrow keys, Home or End when focused on the Library/History tabs to switch collections.
  • Export, Import & Server Sync — custom snippets sync automatically with the server (/api/library) across devices, and can also be exported or imported as a JSON file backup.
  • History stays lean — configurable cap (default 50, up to 5,000 on Team) persisted across server restarts. Clear individual commands or wipe history with confirmation.

Remote access #

Your computer stays home. You don't have to. One click gives WebTun a public HTTPS address.

Settings → Tunnel → Create. The app fetches the official Cloudflare connector on first use (verified download, nothing bundled) and hands you a https://….trycloudflare.com URL.

Open it anywhere — phone, tablet, a friend's laptop. Same PIN, same sessions, same files.

Tunnels persist. Restart the server and your tunnels are remembered and re-validated automatically. Copy the URL any time from the tunnel list. If a tunnel dies it's restarted on its own — backing off from 30s up to 5 minutes, and giving up after 5 tries (it's then shown as dead so it stops churning) — and a recycled process ID can't be mistaken for your live tunnel. Stop always removes the entry, even a dead one; reopening Settings re-syncs the list.

A public URL is public. Always set a strong PIN before creating a tunnel — an open instance with a tunnel is an open door.

SSH access #

Love the browser — but sometimes you need Termius on your phone, VS Code on your laptop, or rsync in a script. SSH Access mints key-only credentials on demand. Nothing exists until you ask.

Set a PIN first. Key generation is refused on unprotected instances — shell access must never be one click away for anyone on the network.

Enable SSH in Settings → Features. The feature ships off. Turning it off stops this process's built-in server, disconnects a WebTun-started Tailnet, and prevents new keys. Installed keys are retained, and a system SSH server can still accept them: use Revoke to remove individual keys. A persisted PID alone never authorizes WebTun to kill a daemon; a surviving listener after an abnormal shutdown needs owner inspection.

Easy setup does the homework. The top of the SSH panel checks the server, the listener, the firewall and Tailscale — tap Fix it on any red row and the app runs the repair itself (passwordless sudo only; otherwise it shows the exact command). No system sshd? Start the built-in SSH — zero privilege needed. For the phone path, Connect on the Tailscale row (paste an auth key for headless, or tap the sign-in link).

Label + Generate. Name the credential after the device ("Termius on iPhone"). The app creates an ed25519 key and installs the public half for the server user — the same identity your web terminals already use, so files and permissions match.

Copy the OpenSSH-format private key now. It is shown once and not retained in WebTun state. Native generation stays in memory; the exceptional ssh-keygen fallback uses a short-lived temporary file which is cleaned up. Save it as ~/.ssh/webtun-key (chmod 600) or import it into your SSH client. Verify the host fingerprint on first connect.

Revoke any time. Each key has its own Revoke button; only WebTun-tagged entries are removed, your other keys are untouched. Up to 32 keys.

Key-only, no passwords. SSH here is the same user as your terminals, reachable over LAN, Tailscale, or a Cloudflare TCP route — the panel shows the right address for each. If sshd isn't listening yet, it prints the one-time setup commands for your OS (run them yourself; WebTun never edits system SSH config). If your sshd uses a non-default port, set the same Expected SSH port so the recipes match; and if the panel ever reports orphaned entries (keys without records), one click removes them.

Phone says "timed out"? The address is unreachable — not the key. Checklist: never use 127.0.0.1 from your phone (server-only); LAN addresses (192.168.x.x) work only on the same Wi-Fi; on mobile data use the Tailscale IP (Tailscale on server + phone, same account) or the server's public IP with the SSH port open in the firewall (sudo ufw allow 2222/tcp). Retest from a laptop with ssh -v to see how far the handshake gets.

Sessions & security #

A PIN keeps strangers out. Device approvals keep surprises out — even from people who know the PIN.

  • Local tunnel targets accept http://localhost:PORT, http://127.0.0.1:PORT, and http://[::1]:PORT. Metadata and link-local destinations remain blocked.
  • Remember this browser as safe. Check "Remember this browser as safe" on the PIN screen to bypass PIN entry on future visits. Trusted browsers receive a cryptographic safe token stored only as a SHA-256 hash on the server and valid for 90 days.
  • Manage trusted safe browsers. In Settings → Security → Trusted safe browsers, view all remembered devices with their browser details, IP address, and last-seen activity. Revoke any browser individually or click Revoke other trusted browsers to de-authorize remote machines while keeping your current browser.
  • Automatic revocation on PIN change. Changing the PIN rotates the master secret and immediately purges all remembered safe browsers and active sessions, ensuring former devices cannot reconnect without the new PIN.
  • New devices wait in line. When someone signs in while you're active, their session stays pending until you approve it from your screen. It lapses automatically after 5 minutes.
  • Review every login. The triangle badge in the header collects unreviewed sign-ins — open the security review to see what, where, and when.
  • Revoke in one click. The sessions list shows every active device; kicking one drops its connections instantly — or sign out all other devices at once and keep only this one.
  • The coffee cup watches the fort. The header cup keeps your screen awake during long jobs (Wake Lock), and the number on it is your live session count — a glance tells you if someone else is in. Click the number to open the security review.
  • Fresh-device PIN changes need another trusted session. A session under 10 minutes old must wait for a different active device to approve, unless it is the sole session or first setup. Older trusted sessions can change immediately. Rotation revokes old tokens; an approving device receives a replacement token.
  • Rate-limited auth & Security Audit Log slow brute-force guessing, and every sign-in, session approval/revocation, PIN rotation, SSH key event and runtime policy update is recorded to a persistent server-side audit log (Settings → Security → Security Audit Log) with live filtering plus 1-click JSON and CSV export.
  • Runtime Access Policy in Settings → Security lets administrators inspect and update allowed WebSocket origins and preview port allow-lists at runtime without restarting the server.

Trusted devices remember you via a session token in the browser. Use them on personal machines; approve-and-forget on shared ones.

Plans & license #

Free covers homelab life. Pro and Team pay for commercial use — and the keys work offline.

  • Community (free): noncommercial use, 2 concurrent tunnels, 3 trusted devices, 200 history entries. Up to 3 terminals and 10 file tabs. Free includes the System and Light themes; additional color palettes require Pro or Team.
  • Pro ($3/server/month, $115/year): commercial use, unlimited tunnels, 5 devices, SSH keys for Termius and VS Code, 1,000 history entries.
  • Team ($19/seat/month, $182/seat/year, 3 minimum): commercial use, unlimited tunnels, 3–10 trusted-device seats, 5,000 history entries, server-synced command library & bookmarks, JSON/CSV security audit export, and runtime access policy controls.
  • Activate in Settings → Security → License. Paste the key once — the server checks its signature locally and stores it at 0600. No account, no call home per request.
  • Expiry is gentle. Paid keys get a 7 day grace period with a banner; afterwards SSH provisioning and extra tunnels pause. The local terminal never locks.
  • Buy, renew or manage billing in Settings → Security → License. Open Purchase or renew a license, choose Pro/Team, Monthly/Yearly and Team seats, then Request license by email — a ready-made email to ptelgm.yt@gmail.com is generated for you to send; we reply with your key and payment details. If the server owner has configured Stripe, Pay with Stripe is also available.
  • Paid periods, not approximations. Keys retain the verified plan/seats and expire at the paid subscription/invoice period end. Duplicate webhook deliveries reuse one entitlement and cannot resurrect a claimed key. A renewal older than the active key is kept but cannot downgrade it.
  • Unconfigured Community installs keep their existing behavior. Caps remain dormant until WEBTUN_LICENSE_PUBLIC_KEY is set. Checkout also needs Stripe credentials, matching monthly/yearly price IDs and a signing key on the trusted billing host. No automatic six-month migration timer is implemented.

Make it yours #

Settings is one panel, seven collapsible sections — Security, Appearance, Terminal, Interface, Features, Tunnel, System — plus a static About card with the version.

  • Nine palettes plus System — Midnight OLED through Monokai, each tuned for legibility. The terminal follows your choice, and System tracks your OS light/dark setting automatically.
  • Tune the terminal (font, size, cursor style, blink, bell, scrollback, right-click paste), the interface density — and toggle the Git panel off entirely if you never use it.
  • Idle screensaver. Leave the app alone for N minutes and it drifts into a dashboard view — set the timeout, or hit Start now to preview it.
  • Search your settings. The panel has its own live filter — type "wake" or "pin" instead of hunting through seven sections.
  • Reset settings restores defaults in one click if an experiment goes sideways — including live side-effects (data-saver pulse restarts, a held wake lock is released). Your files and PIN are untouched.

Mobile & desktop #

WebTun is a web app that refuses to feel like one.

  • Install it from the browser (menu → Install / Add to Home Screen) — or tap the install banner when it appears, with extra guidance on iOS. As a PWA it launches full-screen, works through network blips, and nudges you — never force-reloads — when an update is ready.
  • Desktop app (Electron) bundles the server: double-click and it picks a free port automatically if 3000 is busy. Enable Start on Login to have it waiting after every reboot. Exit app sits in the System section at the bottom of the Settings panel — one tap stops the server and closes every session cleanly.
  • Desktop updates itself: the packaged app checks GitHub releases shortly after launch and then daily, downloads in the background, notifies you, and installs on quit — no manual download. Available for Windows (Setup + portable), Linux (deb + AppImage) and macOS (arm64 dmg + zip); Intel Macs are not served by current builds.
  • Touch-friendly throughout — file actions, git hunks and approvals are all big-target buttons, not hover-only menus. The Settings drawer uses compact padding and section spacing, with phone-friendly fields and buttons.
  • Gestures: swipe a tab sideways to close it, pull down to refresh, pinch to resize terminal text (that size lasts for the session only — set your default in Settings → Appearance), and flip on Selection mode when you need to copy output instead of tapping it.
  • Mobile extras: enable Show Mobile Keys in Settings → Interface for a compact on-screen keys row (terminal only). Swipe the row horizontally to reach all shortcuts; the Ctrl and selection rows use the same compact spacing. Bottom navigation uses a compact 44px control row with a matching new-session button. The workspace automatically follows the browser’s live screen height on resize, rotation and app resume. In full-screen iPhone Home Screen mode, its background reaches the screen edge while navigation buttons stay above the rounded corners and home-indicator area. When the terminal keyboard opens, navigation hides and the shortcut row sits above the keyboard without extra gesture-area padding; closing it restores the full workspace height. Enable Data Saver to pause live gauges and background preloads on metered connections.

Settings panel #

Panels, dialogs and menus leave the workspace behind them clear, without backdrop dimming or blur, on desktop and mobile. Outside-click dismissal still works for panels and dismissible dialogs.

Open the header's Settings button for Security, Appearance, Terminal, Interface, Features, Tunnel and System, plus About links. Search stays at the top while you scroll. Select a section heading to expand it; its open state is remembered. On desktop, hovering briefly previews a closed section, and clicking keeps it open. Search temporarily expands matching sections and restores your previous layout when cleared. If nothing matches, a message suggests trying a section name; press Escape to clear the search. On phones, text fields sit beneath their labels and action buttons wrap to fit. Keyboard users can activate section headings with Enter or Space; collapsed controls stay out of the tab order.

Shortcuts #

The complete set — also available any time inside the app from the overflow menu → Keyboard Shortcuts.

The connection dot in the header opens System Stats with Enter or Space. Dialogs keep keyboard focus inside until closed; the guide’s section search uses arrow keys and Enter, and each troubleshooting answer announces whether it is expanded.

CtrlK / ⌘KQuick search & command palette (universal)
CtrlPFile finder (when outside terminal; in terminal passes to fzf/readline)
CtrlTNew terminal tab (when outside terminal)
CtrlShiftWClose tab (universal; protects Ctrl+W for vim/bash)
CtrlWClose tab (when outside terminal)
CtrlBToggle file explorer (when outside terminal; in terminal passes to tmux)
Alt1…9Jump to tab 1–8 / last tab (universal)
CtrlShift→/←Cycle tabs
CtrlShiftTReopen last closed tab
CtrlShiftDDuplicate current tab
CtrlShiftPPin / unpin active tab
F2Rename active tab (in terminal) / Rename file (in explorer)
DelDelete focused item (in file explorer)
CtrlNNew file (in file explorer)
CtrlSSave editor file
Middle-clickClose tab
Right-click tabTab menu (pin, color, close…)
CtrlShiftRRefresh preview
AltGToggle Tile View grid
EscRestore maximized tile (in Tile View) / Close menus / dialogs (in terminal passes to vim/TUI)
tip
curl -s http://localhost:3000/api/version
# → {"version":"…"} — quick check the server is alive

Troubleshooting #

The fixes that solve almost everything.