v0.1 bf7c821

README.md RawHistoryFolder

Dumber — a tiny, dumb browser for Wayland

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

  • Native GUI via WebKit2GTK (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..) — a tiny companion that plays nicely with your launcher.
  • Uses a native WebKit2GTK 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: WebKit2GTK and GTK dev packages (examples)
    • Debian/Ubuntu: libwebkit2gtk-4.1-dev libgtk-3-dev build-essential
    • Arch: webkit2gtk gtk3 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 WebKit2GTK

  • The GUI requires building with -tags=webkit_cgo and CGO enabled.
  • Ensure WebKit2GTK and GTK 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.

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

  • 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 — a tiny, dumb browser for Wayland
2
3Dumber is a minimalist browser and launcher companion focused on speed and simplicity. It ships a built‑in WebKit2GTK window for navigation and a CLI with dmenu‑style launcher integration (rofi, fuzzel).
4
5- Native GUI via WebKit2GTK (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..) — a tiny companion that plays nicely with your launcher.
12- Uses a native WebKit2GTK 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: WebKit2GTK and GTK dev packages (examples)
31  - Debian/Ubuntu: `libwebkit2gtk-4.1-dev libgtk-3-dev build-essential`
32  - Arch: `webkit2gtk gtk3 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 WebKit2GTK
108- The GUI requires building with `-tags=webkit_cgo` and CGO enabled.
109- Ensure WebKit2GTK and GTK 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## Project Structure
117- `main.go`: CLI/GUI entrypoint, `dumb://` scheme, service wiring
118- `internal/cli`: Cobra commands (`browse`, `dmenu`, `version`)
119- `internal/config`: Viper‑backed config, XDG helpers, defaults
120- `internal/db`: SQLite schema init and sqlc‑generated queries
121- `services`: app services (parser/history/config/browser)
122- `pkg/webkit`: WebKit2GTK bindings (CGO and stub implementations)
123- `frontend`: TypeScript homepage UI bundled into the binary
124
125## Security & Privacy
126- History and zoom settings are stored locally in SQLite under XDG state.
127- The `tmp/` directory is ignored by Git and kept out of history.
128
129## Roadmap
130- Full Vim-style motion and keyboard navigation across pages and UI.
131- Performance work: faster startup, lower memory, snappier UI.
132- Basic ad-block extension — because fuck ads.
133- Other shiny things I’m not yet aware of.
134
135## License
136This 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