v0.2.0 759cc92

README.md RawHistoryFolder

Dumber, fully unfeatured unbloated browser for tiling WMs

Dumber is a minimalist browser and launcher companion focused on speed and simplicity. It ships a built‑in WebKitGTK (GTK4) window for navigation and a CLI with dmenu‑style launcher integration (rofi, fuzzel).

  • Native GUI via WebKitGTK 6 (GTK4, CGO) with an embedded homepage UI.
  • CLI that parses URLs, supports search shortcuts (e.g., g:query), and integrates with rofi/dmenu.
  • Persistent history and per‑domain zoom levels (SQLite, XDG locations).
  • Configurable via config.json and environment variables, with live reload.

Wayland‑First

  • Dumb on purpose, designed for Wayland window managers (Sway, Hyprland, River, Niri, etc..) it's a tiny companion that interact nicely with your launcher.
  • Uses a native WebKitGTKdo i window; no external browser required and no X11/XWayland dependency.
  • Optimized for dmenu‑style launchers (rofi, fuzzel, wofi) and keyboard‑driven workflows.

Status

  • Very early stage, expect sharp edges and breaking changes, but it works well enough to browse and play with the launcher flows.

Features

  • Built‑in browser window (no external browser needed)
  • Custom dumb:// scheme serving embedded frontend assets
  • Keyboard shortcuts: DevTools (F12), Omnibox toggle (Ctrl/Cmd+L), Zoom In/Out/Reset
  • Persistent history with search and stats
  • Per‑domain zoom persistence
  • dmenu‑style launcher integration (rofi, fuzzel) with history and shortcut suggestions

Quick Start

Prerequisites:

  • Go 1.25+
  • Node.js 20+ (for building the embedded frontend)
  • For GUI build: WebKitGTK 6 and GTK4 dev packages (examples)
    • Debian/Ubuntu: libwebkitgtk-6.0-dev libgtk-4-dev build-essential
    • Arch: webkitgtk-6.0 gtk4 base-devel

Build options:

  • GUI (recommended):
    • make build-gui # builds with -tags=webkit_cgo
    • Run: ./dist/dumber # opens the embedded homepage
  • CLI‑only (no GUI, CGO disabled):
    • make build-static
    • Run: ./dist/dumber-static version
  • Full build pipeline (frontend + Go):
    • make build

Development:

  • make dev runs go run . (non‑CGO; GUI stubs log to console)
  • make test runs tests; make lint runs golangci‑lint

Install

  • CLI‑only (no native window):
    • go install github.com/bnema/dumber@latest
    • Useful everywhere; runs the CLI and non‑CGO flows. In this mode the GUI code is stubbed (no native window shown).
  • GUI build (Wayland + WebKit2GTK via CGO):
    • Ensure WebKit2GTK/GTK dev packages are installed (see prerequisites) and CGO is enabled in your environment.
    • go install -tags webkit_cgo github.com/bnema/dumber@latest
    • If pkg‑config can’t find headers, set PKG_CONFIG_PATH appropriately or prefer make build-gui.

Usage

  • Open a URL or search:
    • dumber browse https://example.com
    • dumber browse example.com # scheme auto‑added
    • dumber browse g:golang # Google search via shortcut
  • Launch the GUI directly:
    • dumber # no args → opens GUI homepage
  • Launcher integration (dmenu‑style examples):
    • rofi: dumber dmenu | rofi -dmenu -p "Browse: " | dumber dmenu --select
    • fuzzel: dumber dmenu | fuzzel --dmenu -p "Browse: " | dumber dmenu --select

Dmenu mode invocation

You can invoke dmenu mode in two ways:

  • Subcommand (recommended): dumber dmenu … and dumber dmenu --select
  • Root flag (generate options only): dumber --dmenu

Note: The root flag path only generates options; for processing a selection (--select), use the dmenu subcommand as the receiving command.

In GUI mode the app serves an embedded homepage via dumb://homepage, and frontend assets under dumb://app/....

Configuration

Dumber follows the XDG Base Directory spec:

  • Config: ~/.config/dumber/config.json
  • Data: ~/.local/share/dumber
  • State: ~/.local/state/dumber (default DB lives here)

A default config.json is created on first run. Key fields:

  • database.path: SQLite database path (defaults to XDG state dir history.db)
  • search_shortcuts: map of search shortcuts, e.g.
    {
      "g":  { "url": "https://www.google.com/search?q=%s", "description": "Google" },
      "gh": { "url": "https://github.com/search?q=%s",    "description": "GitHub" }
    }
    
  • appearance: default fonts and base font size for pages without specified fonts
  • dmenu: options for launcher integration (history count, prefixes, etc.)

Environment variables use the DUMB_BROWSER_ prefix (managed by Viper). Examples:

  • DUMB_BROWSER_DATABASE_PATH=...
  • DUMB_BROWSER_DMENU_MAX_HISTORY_ITEMS=50

Config changes are watched and applied at runtime when possible.

Data Model

SQLite tables (created automatically):

  • history(id, url, title, visit_count, last_visited, created_at)
  • shortcuts(shortcut, url_template, description, created_at)
  • zoom_levels(domain PRIMARY KEY, zoom_factor, updated_at)

Building With WebKitGTK 6 (GTK4)

  • The GUI requires building with -tags=webkit_cgo and CGO enabled.
  • Ensure WebKitGTK 6 and GTK4 dev headers are installed (see prerequisites).
  • Make targets handle both frontend and Go build steps:
    • make build-gui (CGO enabled)
    • make build (CGO enabled by default in the Makefile’s main build)

Without the native tag, a stub backend is used: you can still run CLI flows and see logs, but no native window is displayed.

Media (GStreamer) Requirements

WebKitGTK uses GStreamer for media playback. Install the following packages to ensure audio/video work correctly.

  • 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
    • Optional hardware accel: gstreamer-vaapi
  • 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
    • Optional hardware accel: gstreamer1.0-vaapi

Theme and Runtime Updates

  • The homepage and pages respect your system’s light/dark preference.
  • The app updates color‑scheme live when your GTK theme changes (no relaunch needed).

Project Structure

  • main.go: CLI/GUI entrypoint, dumb:// scheme, service wiring
  • internal/cli: Cobra commands (browse, dmenu, version)
  • internal/config: Viper‑backed config, XDG helpers, defaults
  • internal/db: SQLite schema init and sqlc‑generated queries
  • services: app services (parser/history/config/browser)
  • pkg/webkit: WebKit2GTK bindings (CGO and stub implementations)
  • frontend: TypeScript homepage UI bundled into the binary

Security & Privacy

  • History and zoom settings are stored locally in SQLite under XDG state.
  • The tmp/ directory is ignored by Git and kept out of history.

Roadmap

  • WebKitGTK 6 (GTK4) migration — almost complete (GPU/Vulkan path landed).
  • GPU rendering (Vulkan via GTK4 renderer) with graceful CPU fallback.
  • Full Vim-style motion and keyboard navigation across pages and UI.
  • Performance work: faster startup, lower memory, snappier UI.
  • Basic ad-block extension — because fuck ads.
  • Other shiny things I’m not yet aware of.

License

This project is licensed under the MIT License. See LICENSE for details.

source
1# Dumber, fully unfeatured unbloated browser for tiling WMs
2
3Dumber is a minimalist browser and launcher companion focused on speed and simplicity. It ships a built‑in WebKitGTK (GTK4) window for navigation and a CLI with dmenu‑style launcher integration (rofi, fuzzel).
4
5- Native GUI via WebKitGTK 6 (GTK4, CGO) with an embedded homepage UI.
6- CLI that parses URLs, supports search shortcuts (e.g., `g:query`), and integrates with rofi/dmenu.
7- Persistent history and per‑domain zoom levels (SQLite, XDG locations).
8- Configurable via `config.json` and environment variables, with live reload.
9
10## Wayland‑First
11- Dumb on purpose, designed for Wayland window managers (Sway, Hyprland, River, Niri, etc..) it's a tiny companion that interact nicely with your launcher.
12- Uses a native WebKitGTKdo i window; no external browser required and no X11/XWayland dependency.
13- Optimized for dmenu‑style launchers (rofi, fuzzel, wofi) and keyboard‑driven workflows.
14
15## Status
16- Very early stage, expect sharp edges and breaking changes, but it works well enough to browse and play with the launcher flows.
17
18## Features
19- Built‑in browser window (no external browser needed)
20- Custom `dumb://` scheme serving embedded frontend assets
21- Keyboard shortcuts: DevTools (F12), Omnibox toggle (Ctrl/Cmd+L), Zoom In/Out/Reset
22- Persistent history with search and stats
23- Per‑domain zoom persistence
24- dmenu‑style launcher integration (rofi, fuzzel) with history and shortcut suggestions
25
26## Quick Start
27Prerequisites:
28- Go 1.25+
29- Node.js 20+ (for building the embedded frontend)
30- For GUI build: WebKitGTK 6 and GTK4 dev packages (examples)
31  - Debian/Ubuntu: `libwebkitgtk-6.0-dev libgtk-4-dev build-essential`
32  - Arch: `webkitgtk-6.0 gtk4 base-devel`
33
34Build options:
35- GUI (recommended):
36  - `make build-gui`      # builds with `-tags=webkit_cgo`
37  - Run: `./dist/dumber`  # opens the embedded homepage
38- CLI‑only (no GUI, CGO disabled):
39  - `make build-static`
40  - Run: `./dist/dumber-static version`
41- Full build pipeline (frontend + Go):
42  - `make build`
43
44Development:
45- `make dev` runs `go run .` (non‑CGO; GUI stubs log to console)
46- `make test` runs tests; `make lint` runs golangci‑lint
47
48## Install
49- CLI‑only (no native window):
50  - `go install github.com/bnema/dumber@latest`
51  - Useful everywhere; runs the CLI and non‑CGO flows. In this mode the GUI code is stubbed (no native window shown).
52- GUI build (Wayland + WebKit2GTK via CGO):
53  - Ensure WebKit2GTK/GTK dev packages are installed (see prerequisites) and CGO is enabled in your environment.
54  - `go install -tags webkit_cgo github.com/bnema/dumber@latest`
55  - If pkg‑config can’t find headers, set `PKG_CONFIG_PATH` appropriately or prefer `make build-gui`.
56
57## Usage
58- Open a URL or search:
59  - `dumber browse https://example.com`
60  - `dumber browse example.com`        # scheme auto‑added
61  - `dumber browse g:golang`           # Google search via shortcut
62- Launch the GUI directly:
63  - `dumber`                           # no args → opens GUI homepage
64- Launcher integration (dmenu‑style examples):
65  - rofi:   `dumber dmenu | rofi -dmenu -p "Browse: " | dumber dmenu --select`
66  - fuzzel: `dumber dmenu | fuzzel --dmenu -p "Browse: " | dumber dmenu --select`
67
68### Dmenu mode invocation
69You can invoke dmenu mode in two ways:
70- Subcommand (recommended): `dumber dmenu` … and `dumber dmenu --select`
71- Root flag (generate options only): `dumber --dmenu`
72
73Note: The root flag path only generates options; for processing a selection (`--select`), use the `dmenu` subcommand as the receiving command.
74
75In GUI mode the app serves an embedded homepage via `dumb://homepage`, and frontend assets under `dumb://app/...`.
76
77## Configuration
78Dumber follows the XDG Base Directory spec:
79- Config: `~/.config/dumber/config.json`
80- Data:   `~/.local/share/dumber`
81- State:  `~/.local/state/dumber` (default DB lives here)
82
83A default `config.json` is created on first run. Key fields:
84- `database.path`: SQLite database path (defaults to XDG state dir `history.db`)
85- `search_shortcuts`: map of search shortcuts, e.g.
86  ```json
87  {
88    "g":  { "url": "https://www.google.com/search?q=%s", "description": "Google" },
89    "gh": { "url": "https://github.com/search?q=%s",    "description": "GitHub" }
90  }
91  ```
92- `appearance`: default fonts and base font size for pages without specified fonts
93- `dmenu`: options for launcher integration (history count, prefixes, etc.)
94
95Environment variables use the `DUMB_BROWSER_` prefix (managed by Viper). Examples:
96- `DUMB_BROWSER_DATABASE_PATH=...`
97- `DUMB_BROWSER_DMENU_MAX_HISTORY_ITEMS=50`
98
99Config changes are watched and applied at runtime when possible.
100
101## Data Model
102SQLite tables (created automatically):
103- `history(id, url, title, visit_count, last_visited, created_at)`
104- `shortcuts(shortcut, url_template, description, created_at)`
105- `zoom_levels(domain PRIMARY KEY, zoom_factor, updated_at)`
106
107## Building With WebKitGTK 6 (GTK4)
108- The GUI requires building with `-tags=webkit_cgo` and CGO enabled.
109- Ensure WebKitGTK 6 and GTK4 dev headers are installed (see prerequisites).
110- Make targets handle both frontend and Go build steps:
111  - `make build-gui` (CGO enabled)
112  - `make build` (CGO enabled by default in the Makefile’s main build)
113
114Without the native tag, a stub backend is used: you can still run CLI flows and see logs, but no native window is displayed.
115
116## Media (GStreamer) Requirements
117
118WebKitGTK uses GStreamer for media playback. Install the following packages to ensure audio/video work correctly.
119
120- Arch Linux:
121  - `sudo pacman -S gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav gst-plugin-pipewire pipewire pipewire-pulse`
122  - Optional hardware accel: `gstreamer-vaapi`
123- Debian/Ubuntu:
124  - `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`
125  - Optional hardware accel: `gstreamer1.0-vaapi`
126
127## Theme and Runtime Updates
128- The homepage and pages respect your system’s light/dark preference.
129- The app updates color‑scheme live when your GTK theme changes (no relaunch needed).
130
131## Project Structure
132- `main.go`: CLI/GUI entrypoint, `dumb://` scheme, service wiring
133- `internal/cli`: Cobra commands (`browse`, `dmenu`, `version`)
134- `internal/config`: Viper‑backed config, XDG helpers, defaults
135- `internal/db`: SQLite schema init and sqlc‑generated queries
136- `services`: app services (parser/history/config/browser)
137- `pkg/webkit`: WebKit2GTK bindings (CGO and stub implementations)
138- `frontend`: TypeScript homepage UI bundled into the binary
139
140## Security & Privacy
141- History and zoom settings are stored locally in SQLite under XDG state.
142- The `tmp/` directory is ignored by Git and kept out of history.
143
144## Roadmap
145- WebKitGTK 6 (GTK4) migration — almost complete (GPU/Vulkan path landed).
146- GPU rendering (Vulkan via GTK4 renderer) with graceful CPU fallback.
147- Full Vim-style motion and keyboard navigation across pages and UI.
148- Performance work: faster startup, lower memory, snappier UI.
149- Basic ad-block extension — because fuck ads.
150- Other shiny things I’m not yet aware of.
151
152## License
153This project is licensed under the MIT License. See `LICENSE` for details.

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close