2
1
Fork
You've already forked wlbar
0
A small status bar for the River and niri Wayland compositors
  • Go 98.9%
  • Shell 1.1%
Vígh Dániel 095348c173
Some checks failed
ci / test (push) Has been cancelled
ci / lint (push) Has been cancelled
ci: drop the binary release workflow
The AUR packages build from Codeberg's auto-generated source archive
(${url}/archive/vX.Y.Z.tar.gz), which the forge produces automatically for
every tag — no CI involved. release.yml only built and uploaded a prebuilt
binary as a Release asset, which nothing depends on and which kept dying on
the codeberg-tiny-lazy runner. Remove it; a pushed tag is all a release needs.
2026年06月19日 10:30:39 +02:00
.forgejo ci: drop the binary release workflow 2026年06月19日 10:30:39 +02:00
cmd/wlbar rename: river-bar → wlbar 2026年06月05日 14:35:13 +02:00
docs/screenshots docs: condense README; remove bar-preview references 2026年06月02日 13:39:35 +02:00
examples rename: river-bar → wlbar 2026年06月05日 14:35:13 +02:00
internal rename: river-bar → wlbar 2026年06月05日 14:35:13 +02:00
packaging/aur build(aur): wlbar 1.5.1 sha256 2026年06月19日 10:05:16 +02:00
protocols Lower bar to background on fullscreen via wlr-foreign-toplevel 2026年05月27日 08:48:27 +02:00
.gitignore rename: river-bar → wlbar 2026年06月05日 14:35:13 +02:00
.golangci.yml Drop dev-only commands and unstick the CI lint 2026年05月27日 12:12:30 +02:00
config.sample.toml rename: river-bar → wlbar 2026年06月05日 14:35:13 +02:00
CONTRIBUTING.md docs: state fixed-scope, no-toolkit-dependency project goals 2026年06月08日 10:29:01 +02:00
FONT_RENDERING.md Render glyphs through FreeType for hinted, crisp text 2026年05月28日 09:03:11 +02:00
go.mod rename: river-bar → wlbar 2026年06月05日 14:35:13 +02:00
go.sum Render glyphs through FreeType for hinted, crisp text 2026年05月28日 09:03:11 +02:00
LICENSE Open up bridge-bar: docs, tests, CI, KISS config, style examples 2026年05月20日 11:39:40 +02:00
README.md docs: state fixed-scope, no-toolkit-dependency project goals 2026年06月08日 10:29:01 +02:00

wlbar

A small, fast status bar for the River and niri Wayland compositors — configured with a handful of TOML keys instead of CSS + JSON. One config file, sensible defaults, colours from a base16 scheme, icons from any Nerd Font.

wlbar is a vibe-coded project — most of it was written by pairing with an AI coding agent, then reviewed and tested. It targets River's legacy zriver_status_manager_v1 / zriver_control_v1 protocols — the river-classic package (River 0.3.x). The rewritten river 0.4+ drops those protocols and is not supported. Bug reports and patches welcome.

Scope — what wlbar is (and isn't)

wlbar is a status bar with a fixed, predictable feature set that works out of the box, built to stay small and dependency-light. It draws itself directly on a Wayland layer-shell surface.

  • No GTK, no Qt, no widget toolkit — and there never will be. Please don't request features or modules that pull one in.
  • Not waybar. It is deliberately not a scriptable, plugin-driven, CSS-themed bar. The module set and instruction set are fixed on purpose; new capability has to earn its place against complexity and dependencies.
  • Minimal dependencies, minimal config. A handful of TOML keys, conservative defaults, and only the externals a module you actually use needs.

Feature requests that fit this scope (a built-in module following the existing pattern) are welcome; requests for a toolkit dependency or a user-extension mechanism are settled non-goals — see CONTRIBUTING.md.

Styles you can build

Pill geometry and corner radius come from your config; the colours come from a base16 scheme. Each example below is [theme] base16 = "..." plus a few geometry overrides — same modules, different look.

Rounded pillsexamples/rounded-pills.toml (Catppuccin Mocha)

rounded pills

Square blocksexamples/square-blocks.toml (Tokyo Night) — radius = 0, zero margins, full-height blocks.

square blocks

Minimal flatexamples/minimal-flat.toml (Nord) — no [[pill]] groups, just coloured text.

minimal flat

Gruvbox softexamples/gruvbox.toml — warm palette, small corner radius.

gruvbox soft

Numbered tag cellsexamples/numbered-tags.toml (Rosé Pine) — [tags] dots = false.

numbered tag cells

Classic DWMexamples/dwm.toml (Dracula) — 22 px, no pills, numbered cells, hide_icons = true, the iconic #005577 focused tag.

classic dwm

Each file is ~20–45 lines of TOML, mostly geometry. Copy the closest one and swap the base16 line.

Install

go install codeberg.org/vighd/wlbar/cmd/wlbar@latest

Or from the repo:

git clone https://codeberg.org/vighd/wlbar && cd wlbar && go build ./cmd/wlbar

Arch (AUR): wlbar (latest release) or wlbar-git (tip of main):

yay -S wlbar # or wlbar-git

(PKGBUILDs also live under packaging/aur/.)

The renderer rasterises glyphs through FreeType via cgo, so a C toolchain and the FreeType headers must be present when building — freetype2 on Arch, libfreetype6-dev on Debian/Ubuntu.

Running

Start it from River's init (~/.config/river/init, executable) so it comes up with the session:

wlbar &

It attaches a bar to every output and follows monitors as they hot-plug.

Dependencies

Core:

What Arch package
Wayland compositor — River 0.3.x river-classic
fontconfig (fc-match) fontconfig
FreeType (build + runtime) freetype2
a monospace TTF/OTF font ttf-jetbrains-mono (or any)
a Nerd Font for icons ttf-nerd-fonts-symbols
Go 1.26+ (build only) go

Per-module externals, needed only if you use that module:

Module Needs Arch package
audio wpctl; pactl for instant updates wireplumber; libpulse
bluetooth bluetoothctl + BlueZ bluez-utils
pacman checkupdates pacman-contrib
network ping; iwgetid or iwctl for SSID iputils; wireless_tools or iwd
mpris a running MPRIS2 player

A module whose dependency is missing renders nothing rather than crashing the bar, so you only install what you use. The AUR packages list these under optdepends.

Configuration

wlbar reads ~/.config/wlbar/config.toml (or $XDG_CONFIG_HOME/wlbar/config.toml). With no file it runs on defaults — the bar shows up immediately and you tweak from there. The minimum is:

[layout]
left = ["rivertags"]
center = ["clock"]
right = ["battery", "network"]

wlbar --print-config dumps the effective config (yours overlaid on defaults), and a typo'd key prints a startup warning. The annotated config.sample.toml explains every key.

Modules go in three groups — left / center / right. Give a side a background in [pills], or declare explicit [[pill]] groups, to wrap it in a rounded pill.

Reloading: edit the config and pkill -HUP wlbar — it re-reads and restarts in place. A broken edit is logged and the previous config kept, so a typo won't drop your bar. SIGINT / SIGTERM quit.

base16 schemes

Seed the whole palette from a base16 scheme instead of hand-tuning [colors]:

[theme]
base16 = "gruvbox-dark-medium"

The scheme drives the bar background, accents, tag / urgent / low states, and a default colour per module (cpu green, memory yellow, temperature cyan, ...), so a themed bar is colourful with no per-module fg. Any [[pill]] without its own bg is filled from the scheme too. Explicit [colors] and [<module>] fg keys still override it.

wlbar ships no schemes — drop a .yaml in ~/.config/wlbar/themes/<name>.yaml and reference it by <name> (a direct path works too). Both the tinted-theming/schemes and archived base16-schemes formats are read; six ready-to-copy schemes ship under examples/themes/.

For a translucent bar, set just the alpha and leave the colour to the scheme:

[colors]
background_opacity = 0.0 # 0.0 transparent (pills + text only) ... 1.0 solid

[pills] opacity does the same for the pills, so a transparent bar can show the wallpaper straight through them too:

[pills]
opacity = 0.0 # 0.0 transparent ... 1.0 solid; leaves each pill's colour intact

Modules

Name Shows (hover detail in parentheses) Reads from
clock local time (month calendar) time.Now()
rivertags River tag indicators, dots or numbered River status protocol
title focused window title (untruncated) River status protocol
niriworkspaces niri workspace indicators, dots or numbered niri IPC ($NIRI_SOCKET)
nirititle focused window title (untruncated) niri IPC ($NIRI_SOCKET)
battery percentage + icon (time to empty/full) /sys/class/power_supply
network connection state + link speed (SSID, IP, ping) /sys/class/net, ping
audio volume / mute wpctl
cpu load % (per-core breakdown) /proc/stat
memory used / total (detail + swap) /proc/meminfo
temperature hwmon temp, critical highlight (every sensor) /sys/class/hwmon
disk usage of a mount (per-mount) statfs
vpn tunnel up/down (IP) /sys/class/net/<iface>
pacman pending updates (the list) checkupdates
bluetooth connected devices (battery + MAC) bluetoothctl + BlueZ
mpris artist/title + transport buttons (full title) MPRIS2 D-Bus

Most modules show extra detail in a hover popup — noted above — using the bar's own font and palette; no config needed. A module with no data renders nothing, so listing mpris or vpn is safe even when idle.

Click / scroll: left-click a rivertags tag to focus it (right-click toggles, middle-click toggles view); left-click a niriworkspaces cell to focus that workspace; click the mpris ◀ ▶ ⏯ buttons to drive the player; left-click audio to mute, scroll to change volume.

niri: swap rivertagsniriworkspaces and titlenirititle in your layout; the niri modules reuse the [tags] and [title] config sections, so dots/numbered styling and colours carry over. They read niri's JSON IPC over $NIRI_SOCKET (set automatically inside a niri session) and render nothing when that socket is absent, so listing them under River is harmless.

Troubleshooting

  • "no wl_output advertised" — you're not on a Wayland session, or no compositor is running.
  • Text looks wrong — check fc-match "<your font>" resolves to a real font file.
  • River modules empty — needs zriver_status_manager_v1, i.e. the river-classic package (River 0.3.x). The rewritten river 0.4+ dropped these protocols.

When filing bugs, include wlbar --version, wlbar --print-config, and your River version.

Contributing

See CONTRIBUTING.md for dev setup and tests. MIT licensed — see LICENSE.