Skip to content
PylotLightPublic

About

Surffish is a compact Electron browser with isolated Chromium tabs, a vertical glass sidebar, local history and downloads, uBlock Origin-style blocking, optional SOCKS5 proxying, and a Bramble password-fill integration.

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Surffish icon

Surffish

Surf without the noise.

Tabs in a glass sidebar, uBlock Origin's filter lists built in, and a SOCKS5 switch for when you're on someone else's network.

Latest release Platform License: MIT CI Electron 44 Bun

Download for macOS Install with Homebrew

Quick start · Features · Screenshots · Install · Privacy · FAQ · Development


Surffish New Tab page with a landscape photo, the glass tab sidebar open over it listing GitHub, Linear, Apple and Hacker News tabs

The New Tab page, with the tab sidebar card slid out over it.


Surffish is a Chromium browser (via Electron) built around one window and a sidebar. Tabs, pinned sites and tab groups live in a glass card on the left that slides in from the edge, or stays put if you pin it.

The things you'd normally add with extensions are already there: ad and tracker blocking from uBlock Origin's own lists, reader view, split view, a command palette, link previews, screenshots, a reading list, RSS feeds and page watchers. Chrome Web Store extensions still install when you want one.

It's also a quick way to browse through an SSH tunnel. Point it at a local SOCKS5 port, route only the sites you choose, and turn on a kill switch so nothing slips out direct if the tunnel drops.

Quick start

brew tap pylotlight/surffish https://github.com/PylotLight/Surffish.git
brew install --cask surffish

Or grab Surffish-<version>-mac-arm64.zip from the latest release, unzip it and drag Surffish.app to Applications.

Or just run it, no install: npx @pylotlight/surffish (or bunx @pylotlight/surffish). See Run with bunx / npx.

Surffish isn't signed or notarized yet, so the first launch needs one extra step. See macOS says the app is damaged.

Screenshots

New Tab page with a landscape photo, clock and favourite sites, sidebar hidden
New Tab. A rotating nature photo, the time, and your pinned and most visited sites.
Command palette open over the Surffish GitHub repo with the query split
Command palette (⌘K). Every command, open tab and search engine in one box.
The Surffish GitHub repo and linear.app side by side in split view
Split view (⇧⌘=). Two tabs side by side with a draggable divider.
Reader view of a GitHub blog post
Reader view (⌥⌘R). Just the article, with your own type size and theme.
Back button history menu listing Linear, GitHub, Hacker News and Apple
Back/Forward history. Hold or right-click Back or Forward to jump several pages at once.
Settings showing the SOCKS5 proxy, local network and kill switch options, and network rules
SOCKS5 and network rules. One local proxy for everything, extra proxies or Direct for specific sites, LAN addresses direct, and a kill switch.

What it does

Feature What you get Shortcut / where
Sidebar tabs Vertical tabs in a glass card that reveals from the window edge. Pin it open and drag its edge to resize. Pin button at the bottom of the sidebar
Tab groups Named, coloured groups. Cmd-click or Shift-click tabs to select several, then group, pin, move or close them together. Select tabs, then ⌘G
Tab overview & search A grid of every open tab, plus a palette that only searches tabs. ⇧⌘\ · ⇧⌘A
Command palette Commands, open tabs and search keywords (yt lofi, or a bang anywhere: lofi !yt) in one place. ⌘K
Split view Two tabs side by side. Swap panes, pop one out, or move focus between them. ⇧⌘= · ⌥⌘← / ⌥⌘→
Glance Shift-click a link to open it in a floating sheet over the current tab. Keep it as a real tab without reloading. Shift-click · ⌘↩ to keep
Mini window Pop tabs out into small windows that float above other apps (an AI chat, a video, docs; up to 6 at once), then put them back, without reloading. A global shortcut shows/hides them all, or opens a pinned page. Drag one against a screen edge to tuck it away behind a small tab. ⇧⌘M · ⇧⌘Space
Ad and tracker blocking uBlock Origin's default lists plus EasyList, EasyPrivacy, Peter Lowe's list and URLhaus, with cosmetic and scriptlet rules. Turn it off per site. On by default · per site in Settings → This site
SOCKS5 proxy Route all traffic through a local SOCKS5 port (an ssh -D tunnel, for example). LAN addresses go direct by default. Settings → General
Per-site routing & kill switch Send specific sites through other proxies or Direct. The kill switch blocks proxied traffic if the proxy stops answering. Settings → General → Network rules · This site
Private tabs & windows An in-memory session that never writes history or the saved session. ⌥⌘N tab · ⇧⌘N window
Reader view The article on its own, with font, size and theme controls. ⌥⌘R
Reading list Save pages for later, separate from bookmarks, with an unread count. ⇧⌘L
Read Aloud (experimental) Articles, selections or a page from any point read out loud by an on-device voice model (Phonon, 37 English voices, 0.75–3×), with the spoken sentence highlighted. Off by default. ⇧⌘U · right-click → Read Aloud · docs
Bookmarks Bookmark manager, optional bookmarks bar, and import from Chrome, Brave, Edge, Arc, Firefox, Safari or an HTML export. ⌘D · ⌥⌘B manager · ⇧⌘B bar
History Local history with search, plus a Back/Forward menu for jumping several pages. ⌘Y · hold or right-click Back/Forward
Chrome Web Store extensions Paste a store link, or click Add to Surffish on the store page. Extensions with an action get a toolbar button. Settings → Integrations → Extensions
Bramble password manager Built-in integration with the Bramble extension, with a Surffish PIN (and Touch ID) quick unlock so you don't retype the master password. Settings → Integrations
Screenshots Region, visible area, full page, or a scrolling capture you stop where you like. Copy, save or annotate. ⇧⌘S
Downloads Pause, resume, open and reveal downloads from a toolbar popover. ⇧⌘J
PDF viewer & editor Built-in viewer. Edit mode fills forms (calculations and formatting scripts included), signs signature fields with saved signatures or initials, annotates, and rotates, reorders or deletes pages, then saves or flattens a copy. Works for page-made (blob:) PDFs too. ⇧⌘E · ⌘S to save
Feeds RSS, Atom and JSON Feed reader, page feed discovery, and presets for a GitHub repo's releases, commits, tags or Actions runs. Settings → Integrations → Feeds
Page watchers Watch part of a page and get told when it changes. Can be switched off entirely. Settings → Watchers
Spaces Separate sets of tabs, each with its own cookies and proxy. Off by default. Settings → General → Enable Spaces · ⌃1–⌃9
Tab sleep & auto-archive Background tabs sleep after a while and old ones archive themselves (restorable). Tabs playing or paused on media are left alone. Settings → General
Task manager CPU and memory per tab and process, and a way to kill a stuck one. ⇧Esc
Network inspector Opt-in request log for every tab, with HAR export and request mocks. Off by default. Settings → General → Developer
Updates Checks the GitHub releases feed and tells you when a new version is out. Surffish menu → Check for Updates…
The usual Find in page, per-site zoom, HTTPS-only mode, copy clean link (tracking parameters stripped), Picture in Picture, default browser, reopen closed tab. ⌘F · ⌘= / ⌘- · ⌥⇧⌘C · ⇧⌘T

Shortcuts are the macOS ones. Running from source on Linux, ⌘ is Ctrl (History is Ctrl+H, Downloads Ctrl+J).

Install

Surffish ships as an Apple silicon zip on GitHub Releases, and this repo is its own Homebrew tap. It needs macOS 13 Ventura or newer on an M-series Mac.

Homebrew (recommended, updates with brew upgrade):

brew tap pylotlight/surffish https://github.com/PylotLight/Surffish.git
brew install --cask surffish

Manual: download Surffish-<version>-mac-arm64.zip from the latest release, unzip, and move Surffish.app to /Applications.

There are no Intel Mac, Windows or Linux builds. The app runs from source on Linux for development and CI.

Run with bunx / npx

npx @pylotlight/surffish        # or: bunx @pylotlight/surffish

The @pylotlight/surffish package is a tiny launcher (no dependencies). The first run downloads the release zip from GitHub Releases (about 120 MB) with a progress bar, checks its SHA-256 against the one recorded when the package was published, unpacks it with ditto into ~/.cache/surffish/<version> and opens it. Later runs open the cached copy straight away, offline too.

  • npx @pylotlight/surffish@0.1.22 runs that exact release; the package version always matches the app version.
  • --latest runs the newest GitHub release instead, --path prints the cached .app path, --clear-cache frees the space, --help lists the rest. Anything else (a URL, say) is passed to the app.
  • npm i -g @pylotlight/surffish gives you a surffish command.
  • The cache respects XDG_CACHE_HOME. Homebrew is still the better choice if you want /Applications and brew upgrade.
  • bunx @pylotlight/surffish --uninstall removes the cached app and prints what else is left (your profile, caches, keychain item); --uninstall --all deletes those too, after asking.

Same platform limits as above: Apple silicon Macs only. On other systems the launcher says so and exits. More in packages/cli/README.md.

Privacy

  • Your data stays on your Mac. History, the open-tabs session, bookmarks, the reading list and preferences live in one SQLite database (surffish.db) in your profile folder. There's no account and no sync service.
  • Address bar suggestions are local. They come from your own tabs, bookmarks and history, not from a remote suggestion service. Typed searches go to the search engine you pick.
  • Network calls Surffish makes on its own: filter list updates (from uBlock Origin's asset server and the list publishers, at startup when stale and then every 8 hours), New Tab photos, the GitHub releases feed for update checks, and any feeds or page watchers you add. Turning on Read Aloud downloads its voice model once (pinned, hash-checked); the text it reads never leaves your Mac. Preloading (on by default, Settings → General → Tabs) opens a connection to a site while you type its address or hover a link to it, never in private tabs.
  • The proxy is a tunnel, not anonymity. SOCKS5 support routes traffic through an endpoint you control. It's not an audited anonymity tool. WebRTC is kept from leaking your real IP while the proxy is on.

Translation is optional and online. Settings → Languages holds the target language. Translate page updates readable text in the current page; Translate Selection shows a small in-page result. Show original restores unchanged translated text without reloading. Only a requested snapshot of readable text is sent to Google, without site cookies; form values, editable fields, hidden text and code blocks are excluded. Local/private addresses are not translated. This uses Google’s keyless web endpoint, which may be rate-limited or change without notice; no API key is required and availability is not guaranteed. The explicit Open in Google Translate fallback still opens a separate tab and shares the page URL. Source language is detected automatically. Translation covers the main document, not frames, PDFs or text inside shadow roots; large pages may be partially translated, and newly loaded content requires another request.

FAQ

macOS says Surffish "is damaged and can't be opened"

Surffish is unsigned and not notarized, so Gatekeeper blocks a downloaded copy. First make sure it came from the official releases. Then clear the quarantine flag and open it again:

xattr -cr /Applications/Surffish.app

You can also Control-click the app and choose Open on first launch. Clearing quarantine skips Gatekeeper's download check, so only do it for a copy you trust. Homebrew no longer has a --no-quarantine option, so the same step applies to Cask installs.

How do I browse through an SSH tunnel?

Surffish can start an SSH tunnel for you. In Settings → Connection (its own settings tab), under SOCKS5 proxy, enter a host alias from ~/.ssh/config (or user@host), choose a free Shared SOCKS5 port, and Save. Surffish and other local apps use 127.0.0.1:<port>; the SSH-side port is selected automatically and is not exposed as a second setting.

SSH client picks what runs the tunnel. Built-in (default) runs inside Surffish and reads IdentityFile, IdentityAgent, User, Port and known_hosts from your SSH config. System OpenSSH runs your OS ssh (/usr/bin/ssh on macOS) with ssh -N -D, so everything OpenSSH supports works: ProxyJump/jump hosts, ProxyCommand (cloudflared, AWS SSM, gcloud), Match exec, certificates and security keys (FIDO/YubiKey). Pick it when the built-in client can't reach a host your terminal can. Set SURFFISH_SSH_DEBUG=1 to log either client's connection trace.

To use an SSH tunnel you already started yourself, open a dynamic forward in a terminal and leave it running:

ssh -N -D 127.0.0.1:1080 user@your-ssh-host

Then go to Settings → Connection → SOCKS5 proxy, leave the SSH host field blank, set the host and port (127.0.0.1 and 1080 by default), and turn the switch on. The browser and other apps can use that same existing SOCKS5 endpoint directly; Surffish does not open a second fixed port in this mode. Test port only checks that something is listening; it doesn't test the SOCKS handshake or the SSH destination.

To send only some sites through the tunnel, leave the main switch off and add Network rules instead, or open the This site panel on a page and pick a route. Turn on Kill switch if a proxied site should fail closed when the tunnel drops.

Do Chrome extensions work?

Many do. Install from Settings → Integrations → Extensions by pasting a Chrome Web Store link or ID, or click Add to Surffish on the store page. Surffish shims the APIs Electron is missing (tab events, declarativeNetRequest rules, webNavigation and so on), and lists anything only partly supported. Extensions that rely on Chrome-only APIs, or on Chrome's sign-in, may not work.

Where is my data stored?

In ~/Library/Application Support/Surffish. The main file is surffish.db (SQLite, with -wal/-shm next to it), with small JSON files for some settings. Delete the folder to reset Surffish completely. Dev builds use a separate Surffish Dev folder, so they can run alongside the installed app.

Why Electron and not a "real" browser fork?

Electron gives a current Chromium engine with a small, readable codebase on top, so features land quickly and the whole app stays hackable in TypeScript. The trade-off is that a few Chrome features (Chrome sync, some extension APIs) aren't available.

Documentation

Development

You need Bun (version pinned in .bun-version).

git clone https://github.com/PylotLight/Surffish.git
cd Surffish
bun install
bun run dev

bun run test runs the unit tests, bun run typecheck type-checks, and the test:electron-* scripts run Electron smoke tests against a production build. More in docs/development.md.

Contributing

Issues and PRs are welcome. Keep PRs to one change, and include a smoke test or screenshot for UI changes. CI runs on self-hosted runners and doesn't run for pull requests from forks, so a maintainer will run it for you.

License

MIT. Third-party assets (the Bramble icon, New Tab photos) carry their own licenses, listed in docs/third-party-assets.md.


If Surffish makes your browsing a bit quieter, a ⭐ helps other people find it.

About

Surffish is a compact Electron browser with isolated Chromium tabs, a vertical glass sidebar, local history and downloads, uBlock Origin-style blocking, optional SOCKS5 proxying, and a Bramble password-fill integration.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages