How CLIs Communicate with a Running Quickshell Instance: The Complete IPC Breakdown
Omarchy's command-line tools communicate with the active Quickshell process through the Quickshell IPC interface, using Unix-domain sockets via the qs ipc subcommand.
Omarchy's CLI architecture separates the command-line experience from the graphical shell runtime. When you run commands like omarchy-theme-set or omarchy-system-sleep-lock, these tools don't manipulate files directly—they send structured messages to the live Quickshell instance through its inter-process communication (IPC) system. This article explains exactly how that communication works, with reference to the actual implementation in the omacom/omarchy repository.
The Core IPC Mechanism: qs ipc and omarchy-shell
All Quickshell CLI communication in Omarchy flows through a single wrapper script: bin/omarchy-shell. This script constructs the canonical IPC command that every tool uses.
The IPC Command Structure
The underlying invocation follows this pattern:
qs ipc -n -p "$OMARCHY_PATH/shell" call -- <target> <action> [arguments…]
Each component serves a specific purpose:
| Component | Purpose |
|---|---|
qs |
The Quickshell binary executable |
ipc |
Subcommand that opens a Unix-domain socket to the running instance |
-n |
Non-interactive mode (no TTY required) |
-p "$OMARCHY_PATH/shell" |
Socket path—locates the Unix socket under Omarchy's installation |
call -- |
Initiates a call transaction; -- separates qs flags from payload arguments |
<target> |
The QML service registered in Quickshell (e.g., shell, notifications, media) |
<action> |
Method to invoke on that target |
[arguments…] |
JSON-encoded parameters passed to the action |
The shell/README.md documents this syntax as the canonical pattern, with the example:
quickshell ipc -p $OMARCHY_PATH/shell call shell ping
IPC Targets and Their Capabilities
Quickshell exposes multiple IPC targets that correspond to major subsystem services. Each target is implemented as a QML object that registers itself with the IPC system.
The shell Target
The shell target is defined in shell/shell.qml and provides core system operations:
| Method | Purpose |
|---|---|
ping |
Health check; returns ok |
applyTheme |
Applies color and shell configuration JSON |
listPlugins |
Returns JSON array of loaded plugins |
debugBarGeometry |
Returns diagnostic positioning data |
Plugin management specifically delegates to shell/services/PluginRegistry.qml, which implements listPlugins, setPluginEnabled, and related methods.
The notifications Target
Handles Do-Not-Disturb state and OSD messaging:
| Method | Parameters | Returns |
|---|---|---|
setDnd |
true / false |
Confirmation string |
getDnd |
none | "on" or "off" |
The osd Target
Controls on-screen display overlays:
| Method | Parameters |
|---|---|
show |
JSON object with message, duration (seconds), optional styling |
Practical CLI Communication Examples
Health Check: Pinging the Running Shell
omarchy-shell shell ping
# → ok
This verifies that Quickshell is running and responsive. The test/shell.d/runtime-smoke-test.sh test suite uses this as its first validation step.
Applying Themes from CLI Scripts
The bin/omarchy-theme-set script demonstrates multi-argument IPC calls:
#!/bin/bash
colors_payload='{"accent":"#ff6600","background":"#1e1e2e","foreground":"#cdd6f4"}'
shell_payload='{"bar":{"height":24,"position":"top"},"gaps":{"inner":8,"outer":4}}'
omarchy-shell shell applyTheme "$colors_payload" "$shell_payload"
applyTheme receives two JSON objects: color definitions and shell geometry settings. Quickshell applies these without restart.
Toggling Do-Not-Disturb
# Enable DND
omarchy-shell notifications setDnd true
# Check current state
omarchy-shell notifications getDnd
# → on
Listing Loaded Plugins with JSON Processing
omarchy-shell shell listPlugins | jq '.[] | select(.enabled) | .name'
The shell/services/PluginRegistry.qml implementation returns a structured array that CLI tools can filter and transform.
Displaying Custom OSD Messages
omarchy-shell osd show '{"message":"Recording started","duration":3,"icon":"media-record"}'
Response Handling and Error Semantics
CLIs communicate with a running Quickshell instance synchronously—each call blocks until the IPC roundtrip completes. Responses follow consistent patterns:
| Response | Meaning |
|---|---|
ok |
Success, no data returned |
unknown |
Target or action not found |
| JSON object | Structured data (plugin lists, geometry, etc.) |
| Error string | Exception message from QML execution |
The bin/omarchy-shell wrapper handles exit codes: non-zero if the Quickshell binary fails or returns unknown, zero on ok or valid JSON.
Architecture Summary: From CLI to QML
The complete communication flow:
- User invokes
omarchy-theme-setor another CLI tool - Tool sources
bin/omarchy-shell(or constructs equivalentqs ipc …command) qs ipcconnects to Unix socket at$OMARCHY_PATH/shell- Quickshell's IPC system routes to the named
<target>QML object - QML method executes, modifying runtime state or querying internal data
- Textual response returns through the socket
- CLI parses response and presents user-friendly output
This design means Omarchy's shell remains fully scriptable without file-watching hacks or configuration reloads. The same IPC mechanism powers both interactive commands and the automated test suite in test/shell.d/runtime-smoke-test.sh, which exercises ping, summon, status, and other IPC surface area.
Summary
- Entry point:
bin/omarchy-shellwraps all Quickshell IPC operations - Transport: Unix-domain sockets via
qs ipc -p $OMARCHY_PATH/shell - Protocol: Textual
call -- <target> <action> [args…]with JSON payloads - Key targets:
shell(core),notifications(DND/OSD),osd(overlays),media(playback) - Implementation: QML objects in
shell/shell.qmlandshell/services/*.qmlregister themselves as IPC targets - Testing:
test/shell.d/runtime-smoke-test.shvalidates the full IPC surface
Frequently Asked Questions
What happens if Quickshell isn't running when I run a CLI command?
The qs ipc command fails with a connection error and non-zero exit status. CLI scripts that source bin/omarchy-shell will surface this as a failure. Some tools may fall back to file-based configuration changes that apply on next launch, but runtime IPC commands require an active Quickshell instance.
Can I extend the IPC system with custom targets?
Yes. Any QML object in the Quickshell hierarchy can expose IPC methods by integrating with the same registration pattern used in shell/services/PluginRegistry.qml. Your custom service becomes callable via omarchy-shell <your-target> <your-method> once registered.
How does this differ from D-Bus or other IPC mechanisms?
Quickshell uses its own lightweight Unix-socket protocol rather than D-Bus. This avoids D-Bus dependencies and matches Quickshell's single-process architecture. The -p flag lets multiple Quickshell instances coexist with isolated socket paths—critical for multi-user or testing scenarios demonstrated in test/shell.d/runtime-smoke-test.sh.
Where is the socket file located?
The socket path is $OMARCHY_PATH/shell, typically resolving to something like /home/user/.local/share/omarchy/shell or your custom installation prefix. The -n flag ensures qs doesn't require a controlling terminal, enabling script and service integration.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →