Skip to content

Latest commit

 

History

924 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Blanc Browser

Blanc — The browser that gets out of your way

A minimal, open-source desktop browser built around one small Island.
Website · Download · User guide · Security

Blanc replaces the usual tab strip and toolbar with a floating command pill. It keeps the current site, tab switching, navigation, search, and a live blocker count close at hand, then expands when you need more.

  • A quieter interface: Island chrome, the Quick Switcher, tab groups, Quiet Tabs, Glance, and multiple windows without a permanent toolbar.
  • Blocking built in: ads and trackers are filtered at the network layer from bundled, hash-verified EasyList and EasyPrivacy snapshots.
  • Private and local choices: private tabs use a separate in-memory session; local profiles separate site data, history, Favorites, downloads, and remembered permissions.
  • Desktop releases: signed and notarized macOS builds, signed Windows installers, and Linux AppImages, all distributed through GitHub Releases.

Watch Blanc in action

Watch Blanc Browser — A little less browser. (v1.15.0)

Watch the 42-second v1.15.0 Product Hunt tour on YouTube.

Security and trust

Blanc uses Electron and Chromium. Electron is part of the browser's attack surface, so Blanc treats runtime configuration, permissions, dependencies, and release integrity as explicit controls:

  • Public web tabs run with Chromium sandboxing enabled, Node integration disabled, and context isolation enabled. Ordinary sites receive no privileged Blanc bridge.
  • Permissions deny by default. Camera, microphone, location, and notifications require per-site decisions; screen capture and other unhandled permissions are refused.
  • Published macOS builds are signed and notarized, and Windows installers are timestamp-signed. The current release includes a Sigstore-authenticated checksum manifest, a CycloneDX SBOM, and provenance evidence.
  • Vulnerabilities can be reported privately under the response targets and safe-harbor terms in SECURITY.md.

Blanc has earned the OpenSSF Best Practices Baseline Level 1 self-certification. It is a voluntary assessment of documented project practices, not an independent security audit or endorsement. Blanc currently has one human maintainer and has not completed an independent external audit. The evidence and limits for the current release are recorded in the v1.15.0 release report.

Current release: v1.15.0 expands Mahjong to eight layouts, rotates the Daily board across them, adds device-local records and streaks, resumes unfinished play across tabs, and makes Shuffle undoable. Use the v1.15.0 tag for the exact source snapshot associated with the public binaries.

Source and license

Blanc is open source, released under the MIT License. You can inspect the source, build and run it locally, modify it, and publish your own builds. A local build shows what that source does; it is not proof that a published binary is byte-for-byte identical.

Publishing a derivative build carries two conditions the MIT grant does not cover. The bundled EasyList and EasyPrivacy filter lists are redistributed under CC BY-SA 3.0 or later, which requires attribution to The EasyList authors and carries share-alike terms on the redistributed lists and Blanc's derived filter data. And the Blanc and Bananify Creative names and logos are trademarks that a copyright licence does not convey — ship your build under your own name and mark. Details in THIRD-PARTY-NOTICES.md and ASSET-LICENSE.md.

Published macOS releases are signed and notarized, and published Windows releases carry timestamped Authenticode signatures. The release process signs the complete checksum manifest with Sigstore, while Windows and Linux CI artifacts receive GitHub provenance attestations. These records authenticate the published artifacts; they do not make local builds reproducible. See the FAQ for the plain-English version and the release repository for the records.

Free browser, optional Patron

Everything that makes Blanc a browser is free: ad and tracker blocking, encrypted sync, private tabs, tab groups, quiet tabs, and passkeys. Blanc Patron costs $30 a year or $4 a month and adds Named Workspaces on every platform. Creating a named workspace requires an active Patron subscription. Renaming and removing existing workspaces continue to work if it lapses.

The memory benchmark, method, and raw runs are in bench/memory/.

Install

Grab the latest build from Releases: macOS (explicit Apple Silicon and/or Intel dmg/zip artifacts, signed & notarized), Windows (code-signed NSIS installer when included in the release), or Linux (x86_64 AppImage). Installed copies keep themselves current via auto-update.

See the user guide for getting started, browsing, privacy controls, profiles, sync, and updates.

Run it from source

For bug reports, patches, and documentation improvements, see Contributing to Blanc. Report vulnerabilities through the private security reporting process.

npm install
npm start

On first launch, Blanc verifies and compiles the reviewed EasyList + EasyPrivacy snapshots bundled with that release. It does not download filter code at startup. Web navigation waits for that protection; if the build fails, the start page offers Retry or an explicit Continue without blocking. The compiled engine is cached in userData; deleting adblock-engine.v*.bin forces a rebuild from the same bundled snapshot. Search suggestions and bounded usage measurement are both presented on, but cannot send until the first-run choices are saved and can be turned off before continuing. Dev runs use their own userData profile and never send usage events.

To build an installable app: npm run dist (or npm run dist:dir for a quick unpacked build in dist/). Targets: macOS dmg/zip, Windows NSIS, Linux AppImage. assets/sunrise-app-icon.png is the canonical static app-icon source for Linux and iOS, and the brand build copies it to build/icon.png. Windows generates its multi-frame ICO from the canonical transparent Sunrise mark, omitting only its three shortest reflection lines for taskbar scale; macOS uses the appearance-aware Sunrise Icon Composer document.

The island

Resting pill on main: up to eight direct dots combine standalone pinned tabs with the active named group, loose-tab section, or pinned shelf. A window-wide +N counts every omitted tab and opens the full list. Accent means active, pulsing means loading, and hollow means private. Quiet tabs keep their normal dot and click-to-wake behavior.

The pill also shows the active site's favicon and domain and the count of ads/trackers blocked on the page. Click a dot to switch tabs without expanding. The strip behind the pill tints itself with the page's own top-edge color, so the chrome reads as a continuation of the site rather than a bar above it.

Expanded command bar (click the pill): address input, back/forward/reload, favorite (heart), and a tab switcher. Cmd/Ctrl+L summons the same panel as a centered palette over a scrim, from anywhere. Esc, ✕, or clicking outside dismisses. The expanded states float over the page — they never push content around.

Slash commands — type / in the input:

/favorites /history /downloads /settings open internal pages
/new /private /close tab management
/find find in page
/clear clear browsing history
/block-ads toggle ad & tracker blocking
/allow-ads allow ads on the current site
/theme cycle appearance (system → light → dark)

Quick switcher + search — type anything else and the island blends loose local matches (tabs, favorites, history, and groups) with live autocomplete from the search engine selected in Settings. Arrow keys move through the six-row result list; Enter keeps the existing confident-local match behavior, otherwise it searches the exact text you typed. Provider suggestions are presented on and can be disabled before continuing or later in Settings.

Glance (Cmd/Ctrl+Shift+G): choose another tab from the current window and keep it visible as a temporary reference beside the main page. The main page stays dominant; the reference can be changed, made main explicitly, or closed without closing its tab. Narrow windows stack the reference below the main page, and Glance never persists or syncs the relationship.

Private tabs (/private or Cmd/Ctrl+Shift+N): nothing is saved to history, they're excluded from session restore and reopen-closed-tab, and popups they open stay private. Cookies, storage, cache, service workers, HTTP auth, and permission decisions live in a separate in-memory session that is discarded when Blanc quits. The whole chrome shifts to a deeper neutral private theme while one is active, and the pill grows a private ✕ chip for a quick exit.

Auto-updates

Packaged builds self-update via electron-updater against GitHub Releases. Chromium can't be swapped out of a running app — it's compiled into Electron — so, like Chrome itself, staying current means replacing the whole app: bump the electron dependency (it tracks Chromium stable) and version, then npm run release. That builds, signs, and notarizes the macOS artifacts locally (see scripts/release.sh), then dispatches release-windows-linux.yml to build the NSIS installer and AppImage on their native runners and upload them onto the same release. The Windows build signs via Azure Trusted Signing if configured (repo secrets AZURE_TENANT_ID/ AZURE_CLIENT_ID/AZURE_CLIENT_SECRET + repo variables AZURE_TRUSTED_SIGNING_ENDPOINT/AZURE_CODE_SIGNING_ACCOUNT_NAME/ AZURE_CERTIFICATE_PROFILE_NAME/AZURE_PUBLISHER_NAME), else falls back to a traditional cert via CSC_LINK/CSC_KEY_PASSWORD secrets. A release workflow without either complete signing path fails instead of publishing an unsigned Windows press artifact; a traditionally signed build that still has a SmartScreen reputation warning is treated as Preview, not Stable. Running installs pick releases up on their next check (startup + every 4 h, or Check for Updates… in the menu) and prompt to restart. Dev builds (npm start) skip all of this.

How it's put together

src/main/main.js         Window, per-tab WebContentsViews, island overlay, IPC, menu
src/main/adblock.js      Network + cosmetic ad blocking (@ghostery/adblocker-electron)
src/main/pages.js        blanc:// scheme for internal pages + their guarded IPC API
src/main/permissions.js  Deny-by-default permission policy + per-site prompt decisions
src/main/downloads.js    Download tracking (will-download), open/show/cancel actions
src/main/bookmarks.js    Favorites store
src/main/history.js      Visit recording + search
src/main/settings.js     Search engine / adblock / theme / home page settings
src/main/search-suggestions.js  Bounded default-engine autocomplete providers
src/main/store.js        Tiny debounced JSON-file persistence used by all of the above
src/main/context-menu.js Right-click menu for web content
src/main/auth-dialog.js  HTTP basic/digest auth prompt
src/main/updater.js      electron-updater wiring
src/main/preload.js      contextBridge API for the chrome strip + island overlay
src/main/tab-preload.js  contextBridge API for blanc:// internal pages only
src/renderer/            The chrome: strip + resting pill (index.html), island overlay (overlay.html)
src/renderer/pages/      Internal pages: newtab, favorites, history, downloads, settings

Many BrowserWindows, each with many WebContentsViews. Each native window owns an independent runtime for its tabs, groups, chrome surfaces, and local-profile identity. The window's own webContents renders the chrome strip — the slim band the resting pill floats in. Each tab is a separate WebContentsView added to its owning window's contentView; only the active tab's view is attached, so switching tabs is just remove-one/add-another rather than destroying anything. The island's expanded states live in one more WebContentsView — transparent, attached on top only while open — which is how the command bar, palette, and find capsule float over the page instead of reserving space. Tab state lives in the main process; both chrome documents just reflect tabs:updated broadcasts.

Personal keeps the existing root data files and Electron default session. Named local profiles isolate site storage, Favorites, history, download metadata, remembered permissions, and normal/private browsing sessions; the existing Profile Sync consent remains Personal-only.

Security posture: the chrome strip, the overlay, and every tab run with contextIsolation: true, nodeIntegration: false, sandbox: true. Tabs carry tab-preload.js, but each blanc:// host receives only its own bridge methods. The main process independently verifies the exact host, owned WebContents/session/surface, and main frame for every pages:* call. Ordinary web content gets no bridge. The richer browserAPI is attached only to Blanc's chrome documents and is independently sender-checked.

Permissions: deny-by-default. Camera, microphone, geolocation, and notifications surface a per-site Allow/Block prompt in the chrome; the decision is remembered per origin and manageable in Settings. Everything else (screen capture, MIDI, etc.) is refused outright; fullscreen, pointer lock, and sanitized clipboard writes are allowed.

Ad blocking: adblock.js attaches a @ghostery/adblocker-electron engine to session.defaultSession once at startup, covering every tab. Request-level blocking isn't bound by MV3's rule caps. The engine is built from bundled, hash-verified snapshots; blocker scriptlets update only with the signed app snapshot and run with isolated declarations. Blocked requests are counted per tab and surface as the accent badge in the pill. Toggle the engine in Settings (or /block-ads); exempt individual sites per-site (/allow-ads, also editable in Settings).

Internal pages (blanc://newtab, bookmarks, history, downloads, settings) are served over a privileged custom scheme by pages.js — a real origin, so web content can't link into arbitrary local files. The user-facing name for bookmarks is Favorites (heart icon); the identifiers keep the classic name. Fresh profiles can bring Favorites directly from detected Chrome, Edge, Brave, Chromium, or Vivaldi profiles; the Favorites sheet keeps that explicit, deduplicating import available later, alongside the universal bookmarks-HTML fallback. Profile paths and raw browser data never cross into a renderer.

No Chrome extensions — by design. Ad blocking is built in at the network layer (above). On macOS, Blanc can also fill a matching Login item from the installed 1Password desktop app when the user explicitly asks it to. That is a narrow, opt-in SDK integration—not an extension runtime or a Blanc-owned password store. Other password-manager browser integrations generally rely on vendor code-signing allowlists. Bowser, Blanc's former name, appears in Apple's allowlist source through apple/password-manager-resources#1137, but that historical entry is separate from the 1Password feature. Skipping an extension runtime also keeps the whole chrome sandboxed and the app small.

Persistence is deliberately boring: one JSON file per store (settings.json, bookmarks.json, history.json, downloads.json, session.json, site-permissions.json) in userData, written through a shared debounced JsonStore using owner-only permissions and atomic replacement. The retained Profile Sync key is wrapped by the operating system credential service. History is capped at 5000 entries, the download log at 200. Open tabs are restored on the next launch — private tabs excepted.

Theming: one green identity in two lights — bone by day, charcoal by night, pine (deep) or sage (bright) as the accent depending on which — plus a dedicated green-night scope for private tabs. Settings → Appearance (System/Light/Dark) drives Electron's nativeTheme so the chrome, internal pages, and web content all follow one switch, no restart.

Address input is normalized in main.js — "has a scheme," "looks like a domain," or "treat as a search query" (engine selectable in Settings: DuckDuckGo, Google, Bing, Brave). Search-like input also gets best-effort autocomplete from that engine; URLs, input typed in private tabs, pasted values, and sensitive-looking text stay local. The separate Search suggestions toggle is device-local and can disable provider requests entirely.

Keyboard shortcuts

Cmd/Ctrl+T / Cmd/Ctrl+W new / close tab
Cmd/Ctrl+Shift+N new private tab
Cmd/Ctrl+Shift+T reopen closed tab
Cmd/Ctrl+L search, tabs & commands
Cmd/Ctrl+F find in page
Cmd/Ctrl+R reload
Ctrl+Tab / Ctrl+Shift+Tab next / previous tab
Cmd/Ctrl+1…9 jump to tab (9 = last)
Cmd/Ctrl+D add to favorites
Cmd+Alt+B / Ctrl+Shift+O favorites
Cmd/Ctrl+Y history
Cmd/Ctrl+Shift+J downloads
Cmd/Ctrl+Shift+G open / close Glance
Cmd/Ctrl+, settings
Cmd/Ctrl + / / 0 zoom in / out / reset

What's still left

  • Passkeys — WebAuthn works with security keys. On supported Macs, Blanc can also create and use device-bound Touch ID passkeys stored in its own Secure Enclave keychain group. Existing iCloud Passwords and third-party credential-manager passkeys still await Apple's grant of the com.apple.developer.web-browser.public-key-credential entitlement (requested).

Naming continuity

The app was renamed from Bowser to Blanc in July 2026. It keeps the bundle identifier me.bnfy.bowser so existing macOS signing and Gatekeeper identity, installed user data, and the auto-update chain continue to work. The former getbowser.com domain redirects path-for-path to blancbrowser.com.

Known rough edges

  • normalizeAddressInput()'s domain-detection regex is intentionally simple; it'll misclassify some edge cases (e.g. paths with dots in query strings). Known, accepted.
  • Per-site ad-block exceptions cover network-level blocking; cosmetic element-hiding isn't scoped per-site.
  • The downloads page polls while visible instead of receiving push updates — simple, but a push channel would be cleaner.

About

Open-source desktop browser with a minimal Island interface, built-in ad and tracker blocking, private tabs, and releases for macOS, Windows, and Linux.

Topics

Resources

Contributing

Security policy

Stars

12 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages