Skip to content

Bundled Widgets

The repository's widgets/ directory contains examples ranging from minimal API demonstrations to complete integrations. Copy only the widgets you want into your configured widgets_dir, together with the lib/ directory when the widget imports shared modules.

Catalog

Widget Purpose Requirements Inbox publisher
simple.lua Minimal stateful toggle None No
group_demo.lua Groups, shared styling, and popups None No
context-menu.lua Native right-click menu API gh for its example action No
popup-context-menu.lua Popup and context menu on one item None No
inbox-demo.lua Representative inbox test messages Native inbox enabled Yes
brew.lua Homebrew updates in its own popup brew in [app.env].PATH No
brew-inbox.lua Homebrew updates and actions brew in [app.env].PATH Yes
github.lua GitHub notifications popup Authenticated gh; bundled GitHub SVG asset No
github-inbox.lua GitHub notifications Authenticated gh Yes
gitlab.lua Assigned GitLab work items Authenticated glab; optional GITLAB_HOST No
gitlab-inbox.lua Assigned GitLab work items Authenticated glab; optional GITLAB_HOST Yes
network.lua Native network snapshot Network agent No
wifi+vpn.lua Read-only tunnel indicator Network agent No
tailscale.lua Tailscale state and controls tailscale; optional TAILSCALE command setting No
wireguard.lua Network Extension VPN control Service name in lib/secrets.lua No

Choose one presentation

Do not load both presentation variants for the same service:

  • choose brew.lua or brew-inbox.lua
  • choose github.lua or github-inbox.lua
  • choose gitlab.lua or gitlab-inbox.lua

The regular variants own a bar icon and popup. The inbox variants publish snapshots into the shared native inbox and register their operations as source actions.

The Tailscale widget uses left click to bring Tailscale up or down. Its right-click menu lists the currently advertised exit nodes and a Disabled option. Selecting one changes Tailscale's own persistent state; EasyBar does not duplicate the selected node in config.toml.

GitHub and GitLab inbox items expose a dedicated Mark as read action. GitHub also acknowledges the notification through the GitHub API. GitLab publishes assigned work items rather than notification records, so its action updates EasyBar's persistent local read state.

GUI environment

Apps opened from Finder or Spotlight do not inherit .zshrc. Make required CLIs and instance settings explicit:

[app.env]
PATH = "/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin"
GITLAB_HOST = "https://gitlab.example.com"
TAILSCALE = "/opt/homebrew/bin/tailscale"

Authenticate tools in a terminal before starting the corresponding widget:

gh auth login
glab auth login --hostname gitlab.example.com

See Environment for precedence and GUI-launch behavior.

Shared modules and assets

Several examples import retry, shell, text, or secrets from widgets/lib. Preserve that directory structure when copying them. File-backed assets are resolved relative to the widget with easybar.asset(...); copy those assets as well.

Keep the secrets helper at widgets/lib/secrets.lua. Do not place a copy at the top level: EasyBar executes every top-level *.lua file as a widget entrypoint, while files below lib/ are loaded only through require(...). Edit the module before copying wireguard.lua, then copy lib/secrets.lua with the widget.

The GitHub, GitLab, and Homebrew inbox examples keep system_woke immediate for the rest of EasyBar, then schedule their own three-second network settling delay with easybar.after(...). Their read-only refresh checks use the shared pure-Lua retry helper with two- and five-second backoff. Authentication failures and Homebrew/GitHub mutations remain one-shot. Ordinary CLI invocations use easybar.spawn_async(...); shell execution is reserved for examples that genuinely need shell syntax.

Diagnostics

The GitHub, GitLab, and Homebrew inbox widgets emit semantic operation logs:

  • debug for refresh reasons, action routing, and published item counts
  • trace for command attempts, retry scheduling, and wake-delay handling
  • info for user-triggered mutations and cancellation
  • warn or error for invalid responses, exhausted retries, and failed mutations

The widget file name is attached automatically as a structured widget field. Transport byte counts remain trace-only and are emitted once per direction, so normal debug logs focus on what the widget was doing rather than every internal socket boundary.

Lua loader and command failures also appear in EasyBar's logs. The Homebrew examples maintain a bounded brew-widget.log in the configured logging directory. Use Lua Logging, Commands, and Troubleshooting when an example does not update.