# How CLIs Communicate with a Running Quickshell Instance: The Complete IPC Breakdown

> Learn how omarchy CLIs communicate with Quickshell using Unix-domain sockets and the qs ipc subcommand for seamless Inter-Process Communication. Explore the complete IPC breakdown.

- Repository: [Omacom/omarchy](https://github.com/omacom/omarchy)
- Tags: deep-dive
- Published: 2026-09-02

---

**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](https://github.com/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:

```sh
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`](https://github.com/omacom/omarchy/blob/main/shell/README.md)** documents this syntax as the canonical pattern, with the example:

```sh
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

```sh
omarchy-shell shell ping

# → ok

```

This verifies that Quickshell is running and responsive. The **[`test/shell.d/runtime-smoke-test.sh`](https://github.com/omacom/omarchy/blob/main/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:

```sh
#!/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

```sh

# Enable DND

omarchy-shell notifications setDnd true

# Check current state

omarchy-shell notifications getDnd

# → on

```

### Listing Loaded Plugins with JSON Processing

```sh
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

```sh
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:

1. **User invokes** `omarchy-theme-set` or another CLI tool
2. **Tool sources** `bin/omarchy-shell` (or constructs equivalent `qs ipc …` command)
3. **`qs ipc`** connects to Unix socket at `$OMARCHY_PATH/shell`
4. **Quickshell's IPC system** routes to the named `<target>` QML object
5. **QML method executes**, modifying runtime state or querying internal data
6. **Textual response** returns through the socket
7. **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`](https://github.com/omacom/omarchy/blob/main/test/shell.d/runtime-smoke-test.sh)**, which exercises `ping`, `summon`, `status`, and other IPC surface area.

## Summary

- **Entry point**: `bin/omarchy-shell` wraps 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.qml` and `shell/services/*.qml` register themselves as IPC targets
- **Testing**: [`test/shell.d/runtime-smoke-test.sh`](https://github.com/omacom/omarchy/blob/main/test/shell.d/runtime-smoke-test.sh) validates 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`](https://github.com/omacom/omarchy/blob/main/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.