# How the Omarchy Menu System Works: JSONC Schema, Guards, and Providers

> Discover how the Omarchy menu system uses JSONC schema, guards, and providers to build dynamic hierarchical menus. Learn about dotted identifiers and QML providers.

- Repository: [Omacom/omarchy](https://github.com/omacom/omarchy)
- Tags: internals
- Published: 2026-09-13

---

**The Omarchy menu system builds dynamic, hierarchical menus by parsing a JSONC configuration file with dotted identifiers and evaluating shell-based guard expressions, delegating specialized content to registered QML providers.**

Omarchy, an open-source declarative desktop environment, renders its top-level and context menus through a schema-driven architecture defined in the `omacom/omarchy` repository. The system combines static configuration with runtime shell evaluation to control visibility, state, and behavior of menu items. This article examines the mechanics of menu parsing, guard expression evaluation, and provider delegation as implemented in the source code.

## Core Architecture: JSONC Configuration and Dotted Identifiers

The menu structure originates from `default/omarchy/omarchy-menu.jsonc`. Each entry uses a dotted identifier that implicitly defines the menu hierarchy without requiring explicit nesting syntax. For example, the key `trigger.share.file` automatically creates a nested path under **Trigger → Share → File**, where each dot represents a submenu level.

When the QML component `shell/plugins/menu/Menu.qml` initializes, it reads this JSONC file and constructs an internal tree model by splitting the dotted keys. This approach allows flat configuration files to generate deeply nested menu structures while maintaining human readability.

## JSONC Schema Fields and Guard Mechanisms

The schema supports specific fields that act as metadata, execution directives, or conditional guards. These fields are evaluated at runtime to determine the final rendered state of each menu item.

### Execution and Delegation Fields

- **`action`**: Specifies the shell command executed when the user selects the entry.
- **`provider`**: References a named QML provider registered in `Menu.qml` that supplies dynamic submenu content.
- **`aliases`**: Defines alternate searchable names for the entry to improve discoverability.

### Guard Expression Fields

- **`when`**: A shell condition that determines visibility. If the condition evaluates to false, the entry is omitted from the menu entirely.
- **`disabled`**: A shell condition that dims the entry and prevents selection while keeping it visible in the list.
- **`checked`**: A shell condition that displays a checkmark (✓) next to the label when the condition evaluates to true.

### Visual Presentation Fields

- **`icon`**, **`label`**, **`iconFont`**, **`title`**: Control the visual rendering of the menu item, including Unicode icons and display text.

## Runtime Guard Evaluation

Guard expressions are shell commands evaluated during menu rendering. The implementation in `Menu.qml` processes these conditions to apply conditional logic:

**Visibility Filtering** occurs when the `when` field is present. For instance, `"when": "omarchy-hw-laptop"` ensures the entry only appears on laptop hardware by executing the shell condition and checking the exit status.

**State Management** uses the `checked` and `disabled` fields. The `checked` field supports complex expressions like `"checked": "[[ \"$(omarchy-dns)\" == \"Google\" ]]"` to display real-time configuration status. The `disabled` field accepts conditions such as `"disabled": "omarchy-pkg-present spotify"` to gray out options for already-installed services.

## QML Provider System for Dynamic Content

When a menu entry specifies a `provider` field, the system delegates the submenu's content generation to a corresponding QML provider. Providers are defined as entries in the `providers` map within `shell/plugins/menu/Menu.qml`. The `fonts` provider, for example, generates a dynamic font-selection submenu with live previews.

**Provider Limitations**: New providers cannot be added directly in the JSONC configuration. They must be implemented in QML code and registered in the `providers` map before being referenced by name in the `provider` field. This architecture separates static configuration from dynamic content generation, keeping the JSONC file declarative while allowing complex QML logic for specialized submenus.

## The Menu Rendering Workflow

The system processes menu generation through five distinct stages:

1. **Parsing**: `Menu.qml` reads and validates `default/omarchy/omarchy-menu.jsonc`.
2. **Model Construction**: Dotted identifiers are split on periods to build the hierarchical tree structure.
3. **Guard Evaluation**: Shell conditions in `when`, `disabled`, and `checked` fields execute to determine visibility and state.
4. **Provider Resolution**: Entries with `provider` fields trigger the corresponding QML provider to generate dynamic content.
5. **UI Rendering**: Final assembly combines icons, labels, checkmarks, and dimmed states based on the evaluated guards.

## Practical Configuration Examples

Create a laptop-specific tool that shows a checkmark when enabled:

```json
{
  "system.laptop-only": {
    "icon": "󰣇",
    "label": "Laptop Only",
    "action": "omarchy-launch-laptop-tool",
    "when": "omarchy-hw-laptop",
    "checked": "[[ \"$(my-laptop-status)\" == \"enabled\" ]]"
  }
}

```

Delegate to the built-in fonts provider for dynamic font selection:

```json
{
  "style.font": {
    "icon": "",
    "label": "Font",
    "provider": "fonts"
  }
}

```

Disable an install option when the package is already present:

```json
{
  "install.service.spotify": {
    "icon": "󰓇",
    "label": "Spotify",
    "disabled": "omarchy-pkg-present spotify",
    "action": "omarchy-install-service-spotify"
  }
}

```

## Key Source Files

- **`default/omarchy/omarchy-menu.jsonc`**: The central menu definition file containing the JSONC schema, guard expressions, and provider references.
- **`shell/plugins/menu/Menu.qml`**: The QML component that implements provider logic, evaluates guard expressions, and constructs the menu UI.
- **[`docs/menu.md`](https://github.com/omacom/omarchy/blob/main/docs/menu.md)**: Documentation covering schema specifications, guard semantics, and provider implementation requirements.

## Summary

- The Omarchy menu system parses `default/omarchy/omarchy-menu.jsonc` to generate hierarchical structures from dotted identifiers like `trigger.share.file`.
- **Guard expressions** (`when`, `disabled`, `checked`) evaluate shell conditions at runtime to control visibility, selectability, and checkmark states.
- The **`provider`** field delegates dynamic submenu generation to QML implementations registered in `shell/plugins/menu/Menu.qml`.
- Providers require QML implementation; they cannot be defined purely through JSONC configuration.
- Visual attributes combine with conditional logic to create context-aware, hardware-specific menu interfaces.

## Frequently Asked Questions

### What file format does the Omarchy menu system use for configuration?

Omarchy uses **JSONC** (JSON with Comments), which allows standard JSON syntax plus C-style comments and trailing commas. The primary configuration file is located at `default/omarchy/omarchy-menu.jsonc`.

### How do dotted identifiers create menu hierarchies without nested objects?

Dotted identifiers like `trigger.share.file` utilize the dot notation to represent menu depth, where each segment creates a submenu level. The parser in `Menu.qml` splits these keys on periods to build the tree structure automatically, keeping the configuration file flat and readable.

### Can custom providers be created directly in the JSONC configuration file?

No, custom providers must be implemented in QML within `shell/plugins/menu/Menu.qml` and registered in the `providers` map. The JSONC file can only reference existing provider names via the `provider` field; it cannot define new provider logic.

### What is the difference between the `when` and `disabled` guard fields?

The **`when`** field controls visibility: when its shell condition evaluates to false, the entry is completely hidden from the menu. The **`disabled`** field controls interactivity: when true, the entry remains visible but appears dimmed and cannot be selected, typically indicating an unavailable option.