# Dumber, fully unfeatured unbloated browser for tiling WMs

Dumber Logo

https://github.com/user-attachments/assets/394f5f7e-a475-42da-b483-5a58b2ea2f51 A dumb browser that works like your favorite terminal multiplexer. ## Features - **Wayland native**: No X11/XWayland dependency, works with Sway, Hyprland, River, Niri, etc. - **Tabs and workspaces**: Each tab holds a workspace with split or stacked panes. - **Keyboard-driven**: Keyboard workflow inspired by Zellij. - **Smart popup handling**: OAuth flows, window.open(), and popup deduplication for tiling WMs. - **GPU rendering**: Hardware video acceleration with automatic VA-API/VDPAU detection. - **Built-in ad blocking**: UBlock-based network + cosmetic filtering. - **Launcher integration**: dmenu-style with rofi/fuzzel support, shows favicons and history. - **Search shortcuts**: Quick search via bangs (e.g., `!g golang` for Google, `!gi cats` for Google Images). - **Customizable themes**: Light and dark palettes with semantic color tokens. - **Persistent storage**: SQLite for history, favorites, per-domain zoom levels, and sessions. - **Live configuration**: Single config file with hot reload when possible. - **Session management**: Zellij-style session save/restore with automatic snapshots and resurrection. ## Status Dumber is almost feature-complete. Next steps will focus on stability, performance, and bug fixing. Core features work well for daily use but expect some rough edges. Some features are still alpha/experimental (notably consume-or-expel panes) and may change behavior between releases. ## Quick Start ```bash # Download and install wget https://github.com/bnema/dumber/releases/latest/download/dumber_linux_x86_64.tar.gz tar -xzf dumber_linux_x86_64.tar.gz mkdir -p ~/.local/bin && install -m 755 dumber_*/dumber ~/.local/bin/ # Run dumber browse https://example.com ``` See [Install](#install) for AUR, Flatpak, building from source, and runtime dependencies. ## Controls & Shortcuts ### Keyboard Shortcuts #### Browser Controls | Shortcut | Action | Notes | |----------|--------|-------| | **F12** | Open Developer Tools | WebKit inspector | | **Ctrl+L** | Open Omnibox | URL/search input with history | | **Ctrl+F** | Find in Page | Search text within current page | | **Ctrl+=** | Zoom In | Firefox-compatible zoom levels | | **Ctrl++** | Zoom In | Alternative plus key | | **Ctrl+-** | Zoom Out | Works across keyboard layouts | | **Ctrl+0** | Reset Zoom | Return to 100% zoom | | **Ctrl+Shift+C** | Copy URL | Copy current URL to clipboard with toast | | **Ctrl+Shift+P** | Print Page | Open native print dialog | | **Ctrl+R** / **F5** | Reload Page | Refresh current page | | **Ctrl+Shift+R** | Hard Reload | Refresh ignoring cache | | **Ctrl+←** / **Ctrl+→** | Navigate Back/Forward | Browser history navigation | #### Tab Management | Shortcut | Action | Notes | |----------|--------|-------| | **Ctrl+T** | Enter Tab Mode | Modal mode for tab operations | | **Ctrl+Tab** | Next Tab | Quick tab switching | | **Ctrl+Shift+Tab** | Previous Tab | Quick tab switching | | **Ctrl+W** | Close Tab | Close current tab | | **N** / **C** (in tab mode) | New Tab | Create new tab | | **X** (in tab mode) | Close Tab | Close current tab | | **L** / **Tab** (in tab mode) | Next Tab | Navigate to next tab | | **H** / **Shift+Tab** (in tab mode) | Previous Tab | Navigate to previous tab | | **Escape** (in tab mode) | Exit Tab Mode | Return to normal navigation | #### Pane Management | Shortcut | Action | Notes | |----------|--------|-------| | **Ctrl+P** | Enter Pane Mode | Modal mode for pane operations | | **→** / **R** (in pane mode) | Split Right | Create new pane to the right | | **←** / **L** (in pane mode) | Split Left | Create new pane to the left | | **↑** / **U** (in pane mode) | Split Up | Create new pane above | | **↓** / **D** (in pane mode) | Split Down | Create new pane below | | **S** (in pane mode) | Stack Pane | Create stacked pane (Zellij-style) | | **X** (in pane mode) | Close Pane | Close current pane | | **m** (in pane mode) | Move Pane To Tab | Opens a tab picker modal | | **M** (in pane mode) | Move Pane To Next Tab | Moves to the next tab, creates new tab if needed | | **Enter** (in pane mode) | Confirm Action | Confirm pane operation | | **Escape** (in pane mode) | Exit Pane Mode | Return to normal navigation | | **Alt+Arrow Keys** | Navigate Panes | Move focus between panes | | **Alt+Up/Down** | Navigate Stack | Navigate between stacked panes | | **Alt+[** / **Alt+]** | Consume / Expel Pane | Experimental (alpha): merge into sibling stack, or expel out of stack | | **Alt+Shift+[** / **Alt+Shift+]** | Consume / Expel Pane (Vertical) | Experimental (alpha): up/down variants | #### Resize Mode | Shortcut | Action | Notes | |----------|--------|-------| | **Ctrl+N** | Enter Resize Mode | Modal mode for pane resizing | | **←/↓/↑/→** / **h/j/k/l** (in resize mode) | Move Divider | Resizes the nearest split by moving the divider | | **H/J/K/L** (in resize mode) | Move Divider (Inverse) | Inverts the direction | | **+ / -** (in resize mode) | Smart Resize | Grow/shrink the active pane (best-effort) | | **Enter** (in resize mode) | Confirm | Exit resize mode | | **Escape** (in resize mode) | Cancel | Exit resize mode | #### Session Management | Shortcut | Action | Notes | |----------|--------|-------| | **Ctrl+O** | Enter Session Mode | Modal mode for session operations | | **Ctrl+Shift+S** | Open Session Manager | Direct access to session browser | | **S** / **W** (in session mode) | Open Session Manager | Browse and restore sessions | | **Escape** (in session mode) | Exit Session Mode | Return to normal navigation | ### Mouse Controls | Action | Result | Notes | |--------|---------|-------| | **Drag pane divider** | Resize panes | Updates split ratio and persists in session snapshots | | **Ctrl+Scroll Up** | Zoom In | Smooth zoom control | | **Ctrl+Scroll Down** | Zoom Out | Smooth zoom control | | **Mouse Button 8** | Navigate Back | Side button (back) | | **Mouse Button 9** | Navigate Forward | Side button (forward) | | **Two-finger Swipe** | Back/Forward | When supported by touchpad | ### Omnibox/Find Mode (when active) | Shortcut | Action | Notes | |----------|--------|-------| | **Escape** | Close/Clear | Clear input if text present, close if empty | | **Enter** | Execute/Navigate | Navigate to URL or jump to match | | **Shift+Enter** | Previous Match | Find mode: go to previous match | | **Alt+Enter** | Center Match | Find mode: center on match, keep open | | **Tab** | Toggle View | Omnibox mode: switch between history and favorites | | **Space** | Toggle Favorite | Omnibox mode: favorite/unfavorite selected item | | **Ctrl+1-9, 0** | Quick Navigate | Jump to result by number (1-10) | | **↑/↓ Arrow** | Navigate Results | Browse suggestions/matches | | **Hold key 400ms** | Accent Picker | Shows accented variants in any text input (e.g., hold 'e' for è, é, ê, ë) | All zoom changes are automatically persisted per-domain and restored on next visit. ## Install ### Pre-built Binaries (Recommended) Pre-built binaries are available for Linux (x86_64/amd64) in the [releases page](https://github.com/bnema/dumber/releases). See [Quick Start](#quick-start) for installation instructions. ### Arch Linux (AUR) Dumber is available on the [Arch User Repository (AUR)](https://aur.archlinux.org/packages?K=dumber-browser): ```bash # Binary package (pre-built, recommended - fastest install) yay -S dumber-browser-bin # Or build from source (latest git - bleeding edge) yay -S dumber-browser-git ``` Both packages install to `/usr/bin/dumber` and include desktop integration. The binary package downloads pre-built releases from GitHub, while the git package builds from the latest source code. > **Note:** When installed via AUR, the self-updater is automatically disabled. Use `yay -Syu` or your preferred AUR helper to update. ### Flatpak A Flatpak bundle is available in each release. This is the easiest way to install Dumber with all dependencies included: ```bash # Download the Flatpak bundle from the latest release wget https://github.com/bnema/dumber/releases/latest/download/dumber.flatpak # Install it (user-level, no root required) flatpak install --user dumber.flatpak # Run it flatpak run dev.bnema.Dumber browse ``` To uninstall: ```bash flatpak uninstall --user dev.bnema.Dumber ``` ### Dependencies Required for both pre-built binaries and source builds: **Arch Linux:** ```bash # Core WebKitGTK 6.0 and GTK4 sudo pacman -S webkitgtk-6.0 gtk4 # GStreamer for media playback sudo pacman -S gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav gst-plugin-pipewire pipewire pipewire-pulse # Hardware video decoding (required for YouTube, Twitch, etc.) sudo pacman -S gst-plugin-va # VA-API drivers (choose based on your GPU) # AMD: sudo pacman -S mesa # NVIDIA: sudo pacman -S libva-nvidia-driver # Intel: sudo pacman -S libva-intel-driver intel-media-driver ``` **Debian/Ubuntu:** > ⚠️ **Note:** Ubuntu 24.04 LTS ships with GLib 2.80, but this project requires GLib 2.84+ due to newer GTK/WebKitGTK runtime requirements. Use Arch Linux, Fedora 41+, or another distribution with recent GLib packages. ```bash # Core WebKitGTK and GTK4 sudo apt install libwebkitgtk-6.0-4 libgtk-4-1 # GStreamer for media playback sudo apt install gstreamer1.0-tools gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-pipewire # Hardware video decoding (gst-plugins-bad includes VA stateless decoders) # VA-API drivers sudo apt install va-driver-all ``` ### Build From Source **Note**: `go install` will not work for this project because the frontend assets must be built first and embedded into the binary. **Prerequisites:** - Go 1.25+ - Node.js 20+ and npm (for building the embedded TypeScript frontend) - WebKitGTK 6 and GTK4 dev packages: - Minimum runtime versions: WebKitGTK 6.0 >= `2.50`, GTK4 >= `4.20`, GLib >= `2.84` - Debian/Ubuntu: `libwebkitgtk-6.0-dev libgtk-4-dev build-essential` - Arch: `webkitgtk-6.0 gtk4 base-devel` - Verify your system with: `dumber doctor` (or configure `runtime.prefix` for `/opt` installs) **Build options:** - GUI build (default, recommended): - Clone the repo and run `make build` (builds frontend first, then Go with GUI support) - The resulting `./dist/dumber` binary includes the native GUI window - CLI‑only (no native window): - Clone the repo and run `make build-no-gui` - The resulting `./dist/dumber-no-gui` binary runs CLI flows with GUI code stubbed ## Usage - Open a URL, local file, or search: - `dumber browse https://example.com` - `dumber browse example.com` # scheme auto‑added - `dumber browse ./test.html` # local file path (converted to file://) - `dumber browse dumb://home` # built-in home page (stats, shortcuts, etc.) - `dumber browse "!g golang"` # search via bang shortcut - Show version information: - `dumber about` # version, commit, and build date - Check for and install updates: - `dumber update` # check and install if available - `dumber update --force` # force reinstall (skips version check) - Launcher integration (dmenu‑style examples with favicon support): - rofi: `dumber dmenu | rofi -dmenu -show-icons -p "🔍 " | dumber dmenu --select` - fuzzel: `dumber dmenu | fuzzel --dmenu -p "🔍 " | dumber dmenu --select` - `dumber dmenu --interactive` # built-in TUI fuzzy finder - `dumber dmenu --days 7` # show history from last 7 days (default: 30) - `dumber dmenu --most-visited` # sort by visit count instead of recency - Manage browsing history: - `dumber history` # interactive history browser (timeline tabs + fuzzy search) - `dumber history --json` # output recent entries as JSON - `dumber history --json --max 50` # limit JSON output to N entries - `dumber history stats` # show history statistics - `dumber history clear` # interactive time-range cleanup - Clean up data: - `dumber purge` # interactive selection (TUI) - `dumber purge --force` # remove everything (no prompts) - Manage configuration: - `dumber config status` # show config path and migration availability - `dumber config migrate` # add missing default settings to config - `dumber config migrate --yes` # skip confirmation prompt - Manage sessions: - `dumber sessions` # interactive session browser (TUI) - `dumber sessions list` # list saved sessions - `dumber sessions list --json` # output sessions as JSON - `dumber sessions list --limit 50` # limit number of sessions shown - `dumber sessions restore ` # restore a session in a new window - `dumber sessions delete ` # delete a saved session - Manage logs: - `dumber logs` # list sessions with log files - `dumber logs ` # show logs for a session (full ID or unique suffix) - `dumber logs -f ` # follow logs in real time - `dumber logs -n 200 ` # show last N lines - `dumber logs clear` # clean up old log files - `dumber logs clear --all` # remove all log files - Generate documentation: - `dumber gen-docs` # install man pages to ~/.local/share/man/man1/ - `dumber gen-docs --format markdown` # generate markdown docs to ./docs/ - `dumber gen-docs --output ./man` # generate to custom directory ### Dmenu mode invocation You can invoke dmenu mode in two ways: - Piped launcher (generate options): `dumber dmenu` - Receive selection from stdin: `dumber dmenu --select` For a built-in fuzzy finder UI, use: `dumber dmenu --interactive` In GUI mode the app serves an embedded home page via `dumb://home`, and frontend assets under `dumb://app/...`. There is also a WIP config UI at `dumb://config` for viewing/applying settings with live reload. ## Tab Management Each tab holds its own workspace. Each workspace can contain multiple panes (split or stacked). Switch between tabs to switch between independent workspaces. ### How it Works 1. **Enter Tab Mode**: Press `Ctrl+T` to enter tab mode (modal interface with timeout) 2. **Create/Close Tabs**: Use keyboard shortcuts: - `N` or `C` - New tab - `X` - Close current tab 3. **Navigate**: Use `Ctrl+Tab` / `Ctrl+Shift+Tab` for quick tab switching, or `L`/`H` in tab mode 4. **Exit**: Press `Escape` to exit tab mode or wait for timeout ## Pane Management Split your browser window into multiple panes, each running independent web sessions. ### How it Works 1. **Enter Pane Mode**: Press `Ctrl+P` to enter pane mode (modal interface with timeout) 2. **Split or Stack Panes**: Use arrow keys or letter shortcuts: - `→` or `R` - Split right - `←` or `L` - Split left - `↑` or `U` - Split up - `↓` or `D` - Split down - `S` - Stack panes (Zellij-style, shows title bars for collapsed panes) 3. **Navigate**: Use `Alt+Arrow Keys` to move focus between split panes, or `Alt+Up/Down` to navigate within stacked panes 4. **Close**: Press `X` in pane mode to close the current pane ## Session Management Dumber automatically saves your browser session (tabs, panes, split ratios, URLs) and allows you to restore previous sessions. ### How it Works 1. **Automatic Snapshots**: Session state is saved automatically (debounced, every 5s by default) and on graceful shutdown 2. **Session Manager**: Press `Ctrl+O → s` or `Ctrl+Shift+S` to open the session manager modal 3. **Browse Sessions**: View active and exited sessions with tab/pane previews 4. **Restore**: Select an exited session to restore it in a new browser window 5. **CLI Access**: Use `dumber sessions` for an interactive TUI, or `dumber sessions list/restore/delete` for scripting ## Configuration Configuration file: `~/.config/dumber/config.toml` (supports TOML, JSON, YAML) A default config is created on first run. Changes are applied automatically (hot reload). Override any setting with `DUMB_BROWSER_*` or `DUMBER_*` environment variables. **Full documentation**: [docs/CONFIG.md](docs/CONFIG.md) - Complete reference for all settings, workspace controls, shortcuts, styling, and more. ## Development Dumber uses pure-Go bindings (no CGO) but requires GTK4/WebKitGTK runtime libraries for the GUI. ### Environment Set `ENV=dev` to use a local `.dev/dumber/` directory for config, data, state, and cache instead of XDG paths. Useful for testing without affecting your real browser data. ### Make Targets | Target | Description | |--------|-------------| | `make build` | Build frontend + binary (recommended) | | `make build-quick` | Build binary only (faster for backend work) | | `make build-frontend` | Build webui pages (homepage, error, config) | | `make dev` | Run with `go run` | | `make test` | Run tests | | `make test-race` | Run tests with race detection | | `make test-cover` | Run tests with coverage report | | `make lint` | Run golangci-lint | | `make lint-fix` | Run golangci-lint with auto-fix | | `make fmt` | Format Go code | | `make generate` | Generate SQLC code | | `make mocks` | Generate mock implementations | | `make install-tools` | Install dev tools (sqlc, golangci-lint) | | `make check` | Verify tools, build, and tests work | | `make clean` | Remove build artifacts | ### Flatpak | Target | Description | |--------|-------------| | `make flatpak-deps` | Install Flatpak build dependencies | | `make flatpak-build` | Build Flatpak bundle | | `make flatpak-install` | Install Flatpak locally for testing | | `make flatpak-run` | Run the installed Flatpak | | `make flatpak-clean` | Clean Flatpak build artifacts | ### Release | Target | Description | |--------|-------------| | `make release-snapshot` | Build snapshot with goreleaser | | `make release` | Create full release with goreleaser | ## Media (GStreamer) & Hardware Acceleration WebKitGTK uses GStreamer for media playback. Dumber includes automatic hardware video acceleration support that detects your GPU and configures the appropriate drivers. **Hardware Acceleration Features:** - Automatic GPU detection (AMD, NVIDIA, Intel) - VA-API and VDPAU driver configuration - Support for H.264, HEVC, VP9, and AV1 codecs - Significantly reduced CPU usage during video streaming **Required packages:** - Arch Linux: - `sudo pacman -S gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav gst-plugin-pipewire pipewire pipewire-pulse` - Hardware decoding: `gst-plugin-va` (stateless VA decoders - required for WebKitGTK) - VA-API drivers: `mesa` (AMD), `libva-nvidia-driver` (NVIDIA), `libva-intel-driver intel-media-driver` (Intel) - Debian/Ubuntu: - `sudo apt install gstreamer1.0-tools gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-pipewire` - Hardware decoding: `gstreamer1.0-plugins-bad` includes VA stateless decoders - VA-API drivers: `va-driver-all` (covers most GPUs) ## References - puregotk: https://github.com/jwijenbergh/puregotk - puregotk-webkit: https://github.com/bnema/puregotk-webkit - ublock-webkit-filters (filter list releases): https://github.com/bnema/ublock-webkit-filters ## Contribute I will gladly accept contributions, especially related to UI/UX enhancements. Feel free to open an issue and let's discuss it! ## License This project is licensed under the MIT License. See `LICENSE` for details.