Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Wren

A small browser with a hard memory budget. Open as many tabs as you like; Wren keeps the whole browser (engine processes included) under a budget you set, 500 MB by default.

Named for the bird: tiny, loud, everywhere. Runs on Linux and Windows.

How it stays small

No browser engine is light, so Wren doesn't pretend to be. Instead it controls the lifecycle of tabs. A watchdog measures the real memory of the whole process tree every few seconds and walks an escalation ladder:

Tier When What happens What you notice
Freeze A background tab has been idle ~30 s JS and timers stop Nothing
Discard Memory passes ~85% of budget Oldest background tabs drop their renderer (history kept) Tab reloads when you return
Destroy Still over budget View deleted; tab becomes a URL + title placeholder Reload, scroll position lost
Warn The active tab alone exceeds the budget Nothing is killed Memory badge turns red

Restored sessions open as placeholders: only the tab you're looking at loads, so startup is fast and a 40-tab session costs the same as a 2-tab one.

The toolbar badge always shows the live number, e.g. 342 / 500 MB.

Install

Needs Python 3.10+ and uv (or plain pip). No compiler, no admin rights, no system packages.

git clone <this-repo> wren && cd wren
uv venv .venv
uv pip install .
.venv/bin/wren            # Windows: .venv\Scripts\wren

Or for development: uv pip install -e ".[dev]".

Usage

wren                      # restore last session (as lazy placeholders)
wren https://example.com  # open URLs
wren --budget-mb 400      # override the budget for this run

Type in the address bar: full URLs load, bare hostnames get https://, anything else searches DuckDuckGo.

Shortcuts

Key Action
Ctrl+T / Ctrl+W New tab / close tab
Ctrl+L Focus address bar
Ctrl+Tab / Ctrl+Shift+Tab Next / previous tab
Ctrl+R or F5 Reload
Ctrl+F Find in page (Esc closes)
Ctrl+= / Ctrl+- / Ctrl+0 Zoom in / out / reset
Ctrl+Q Quit

Configuration

~/.config/wren/config.json on Linux, %APPDATA%\wren\config.json on Windows. All keys optional:

{
  "budget_mb": 500,
  "soft_ratio": 0.85,
  "freeze_after_s": 30.0,
  "governor_interval_ms": 3000,
  "pressure_interval_ms": 1000,
  "renderer_process_limit": 2,
  "disable_gpu": false,
  "restore_session": true,
  "search_template": "https://duckduckgo.com/?q={query}",
  "home_url": "about:blank"
}

Honest limits

  • The floor is the floor: one live tab costs roughly 250–350 MB because the engine is Chromium (via Qt WebEngine). The budget controls the ceiling: 20 tabs cost about the same as 2.
  • A single heavy page (YouTube, Figma) can exceed the budget on its own while active. Wren shows this (red badge) instead of killing what you're reading.
  • No extensions, no sync, no DRM video. It's for browsing websites.
  • GPU rendering is on by default; software rendering turned out unusably slow in real use. The GPU process costs 50–100 MB (counted in the badge), and on Linux some graphics-driver allocations escape the accounting, so the badge can read slightly low there. disable_gpu: true exists for headless runs or strict accounting.

Google account sign-in does not work (known limitation)

Signing into a Google account directly (accounts.google.com) fails with "This browser or app may not be secure". This is Google deliberately blocking embedded browser engines, and Wren uses one (QtWebEngine). It is not fixable from Wren's side, and it affects every QtWebEngine browser, qutebrowser included.

Why it can't be worked around here: a clean Chrome user-agent is given away by the engine's Sec-CH-UA client-hint headers; spoofing Firefox doesn't help because those Chromium client hints keep getting sent and then contradict the Firefox user-agent, which is itself the signature Google blocks. The one lever that would fix it, turning client hints off, isn't honored by the engine. This was tested directly, not assumed.

Workaround: sign into Google in a mainstream browser (Chrome, Firefox, Edge). Wren handles everything else. If first-class Google support ever becomes essential, the real fix is a different engine, which is a much larger change.

Ubuntu 24.04 sandbox note

Ubuntu 24.04 restricts unprivileged user namespaces, which breaks Chromium's sandbox for pip-installed engines. Wren detects this and disables the engine sandbox for itself (with a loud log line) so pages still render. This is a real security trade-off; prefer trusted sites, or allow user namespaces system-wide if you'd rather keep the sandbox: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 (needs sudo).

Development

uv pip install -e ".[dev]"
pre-commit install
ruff check . && black --check . && pytest --tb=short

The governor logic (governor.py), memory accounting (memory.py), config (config.py), and URL handling (utils.py) are pure and unit-tested. The Qt classes (browser.py, tab.py) are thin glue over those modules and are exercised by running the app (wren --smoke-seconds 20 <urls> prints a memory report and exits; used for measurement).

License

MIT

About

A small browser with a hard memory budget

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages