-
-
Notifications
You must be signed in to change notification settings - Fork 62
ARCHITECTURE_OVERVIEW
How iNiR is put together, from the highest level down to the part that matters for your question.
iNiR is a single-process QML application that runs inside Quickshell. There's no backend daemon, no IPC server, no separate process for services. Everything (the bar, sidebars, notifications, audio control, compositor IPC, config management) lives in one QML runtime talking to system services through D-Bus, sockets, and subprocess calls.
Your apps
|
iNiR shell (bar, panels, notifications, settings, everything)
|
Quickshell (QML shell framework)
|
Niri compositor (windows, rendering, input)
|
Wayland protocol --> GPU
shell.qml is the root. It's a ShellRoot (Quickshell-specific, not a regular QML Item). On load it:
- Force-instantiates critical singletons (Idle, PowerProfilePersistence)
- Waits for
Config.ready(JSON config loaded from disk) - Applies the current theme
- Loads either
ShellIiPanels.qmlorShellWafflePanels.qmlbased on the panel family config - Schedules deferred service loading after the first frame renders
Total cold start to panels visible: under 2 seconds on decent hardware.
The shell has two completely separate visual identities that share the same services layer:
Material ii uses Material Design language with 5 style variants (material, cards, aurora, inir, angel). Bar at the top. Sidebars from the edges. Overview launcher.
Waffle uses Windows 11 Fluent Design. Taskbar at the bottom. Start menu. Action center. Notification center.
They're mutually exclusive at runtime. Switch with Super+Shift+W. Both families read from the same Config singleton and the same services, but use completely different visual token systems (Appearance.* vs Looks.*), different panel definitions, and different settings UIs.
More details: Panel Families
70+ QML singletons handle everything that isn't pure UI:
- Compositor IPC: NiriService talks to Niri via socket, gets workspace/window/output state
- System integration: Audio (PipeWire), Network (NetworkManager), Bluetooth (BlueZ), Battery (UPower)
- Data management: Notifications, clipboard history, events, weather, calendar sync
-
Theming: MaterialThemeLoader watches
colors.json, ThemeService orchestrates the pipeline - Content: AI chat (Gemini/OpenAI/Ollama), YT Music player, anime tracking, Reddit
Services are registered in services/qmldir and available everywhere as singletons.
Full catalog: Services Catalog
One JSON file, one QML schema, one write method:
-
Schema:
modules/common/Config.qml(1385+ lines, 51 top-level sections) -
User file:
~/.config/illogical-impulse/config.json -
Defaults:
defaults/config.json -
Write:
Config.setNestedValue("section.key", value)(the only way that persists) -
Read:
Config.options?.section?.key ?? fallback
Users configure everything through the graphical Settings UI. The JSON file is an implementation detail they shouldn't need to touch.
More details: Config System
Pick a wallpaper and the entire system follows:
Wallpaper image
|
generate_colors_material.py (Material You color extraction)
|
colors.json (full Material 3 palette)
|
MaterialThemeLoader (QML file watcher)
|
Appearance tokens (400+ color/size/animation properties)
|
Every UI component
|
External apps (GTK, terminals, Firefox, VS Code, Discord...)
The pipeline also supports 44 built-in theme presets (Catppuccin, Gruvbox, Nord, etc.) that bypass wallpaper extraction and inject colors directly.
More details: Theming Architecture
A simplified map of what lives where:
| Directory | What's in it | Risk level |
|---|---|---|
modules/common/ |
Config, Appearance, shared widgets | Critical |
services/ |
70+ system integration singletons | High |
scripts/inir |
CLI launcher (2400+ lines of bash) | High |
sdata/ |
Install, update, migrations | High |
defaults/ |
Shipped default config and app configs | Medium |
modules/bar/ |
Top bar (ii family) | Normal |
modules/waffle/ |
Complete Windows 11 family | Normal |
modules/sidebarLeft/ |
AI chat, YT Music, widgets | Normal |
modules/sidebarRight/ |
Toggles, calendar, tools | Normal |
translations/ |
i18n strings (15+ languages) | Low |
Full breakdown: Project Map
iNiR ships as a git repo with an interactive installer:
git clone https://github.com/snowarch/inir.git
cd inir
./setup installTwo install modes:
-
Repo-sync:
./setup installsyncs the repo to~/.config/quickshell/inir/ -
Package-managed:
make installcopies to/usr/share/quickshell/inir/
Updates: ./setup update or inir update (git pull + sync + migrate + restart).
The systemd service wires to the compositor via wants links, not graphical-session.target (which would also start on KDE/GNOME).
More details: Installation, Setup & Update