Architecture Overview¶
EasyBar is split into focused targets and process boundaries.
It has:
- a main macOS status bar app
- a command-line control client
- helper agents for calendar and network data
- a separate Lua runtime process
- shared models and transport types
High-level runtime¶
flowchart TB
Input["AeroSpace / macOS events / user input"] --> App["EasyBar app"]
App --> Lua["Lua runtime process"]
App --> Calendar["Calendar agent"]
App --> Network["Network agent"]
Calendar --> EventKit["EventKit"]
Network --> CoreWLAN["CoreWLAN / network APIs"]
There is also a separate CLI process:
flowchart LR
CLI["easybar CLI"] --> Socket["EasyBar control socket"]
Design goals¶
The project is intentionally opinionated.
Key architectural goals are:
- keep the main UI process focused on rendering and widget coordination
- isolate permission-sensitive APIs in helper agents
- keep cross-process protocols explicit and typed
- prefer native Swift widgets for built-in functionality
- support Lua for custom widgets without making Lua the center of the whole system
- integrate cleanly with an AeroSpace-based workflow
Main process responsibilities¶
The EasyBar target is the main app.
It is responsible for:
- starting the bar UI
- loading and validating config
- creating and positioning the bar window
- rendering native built-in widgets
- hosting the native interaction model
- running and supervising the Lua widget runtime
- consuming snapshots or field data from helper agents
- reacting to control-socket commands
- coordinating updates from macOS, AeroSpace, Lua, and agents
The main app should generally decide how state is presented, not gather every piece of raw system state itself.
Examples:
- the network agent returns Wi-Fi metrics, but EasyBar decides how to render signal bars
- the calendar agent returns normalized event snapshots, but EasyBar decides how they appear in the bar and popups