# How Omarchy’s CLI Router Implements Two-Pass Dispatch Resolution

> Discover how Omarchy's CLI router uses two-pass dispatch resolution to efficiently map commands to scripts and handle arguments. Optimize your command-line workflow.

- Repository: [37signals/omarchy](https://github.com/basecamp/omarchy)
- Tags: internals
- Published: 2026-08-25

---

**Omarchy’s CLI router uses a two-pass dispatch system where the first pass resolves the command group and sub-command to a concrete script path, and the second pass executes that script with remaining arguments to handle option parsing and task execution.**

The `basecamp/omarchy` repository implements a modular command-line interface that separates command routing from execution logic. This architecture relies on a **two-pass dispatch resolution** mechanism defined primarily in the [`bin/omarchy`](https://github.com/basecamp/omarchy/blob/quattro/bin/omarchy) entry point. By decoupling command lookup from argument handling, Omarchy maintains a clean separation between the router's group definitions and the implementation details of individual commands.

## First Pass: Resolving Command Groups and Concrete Scripts

The router’s first pass determines which concrete script should handle the user’s request. When you invoke `omarchy theme set`, the router extracts the **group** (`theme`) and **sub-command** (`set`) from the first two positional arguments.

At the heart of this resolution lies the `GROUP_DESCRIPTIONS` associative array declared in `bin/omarchy`. This map associates group names with human-readable descriptions while the router constructs the target script name using the pattern `omarchy-${group}-${subcmd}`. The router validates the existence and executability of the file at `bin/omarchy-${group}-${subcmd}` before proceeding.

If the group or sub-command is unknown, the router immediately falls back to the help dispatcher rather than attempting execution. This validation step ensures that invalid commands fail fast with a consistent error message.

```bash

# Simplified logic from bin/omarchy

declare -A GROUP_DESCRIPTIONS=(
    [theme]="Theme management commands"
    [update]="System update helpers"
    [toggle]="Feature toggles"
)

group="${1:-}"
subcmd="${2:-}"
shift 2  # Remove consumed arguments

script="bin/omarchy-${group}-${subcmd}"

if [[ ! -x "$script" ]]; then
    echo "Unknown command: $group $subcmd"
    exec bin/omarchy-help
fi

```

## Second Pass: Delegating to Concrete Command Scripts

Once the router identifies a valid concrete script, the **second pass** begins with an `exec` call that replaces the router process with the target implementation. The router passes all remaining arguments (`"$@"`) untouched to the concrete script, allowing sub-commands to implement their own option parsing without interference from the router.

Concrete scripts like [`bin/omarchy-theme-set`](https://github.com/basecamp/omarchy/blob/quattro/bin/omarchy-theme-set) or `bin/omarchy-toggle` contain their own `main()` functions and argument handling logic. They typically use `getopts` or manual case statements to process flags such as `--name` or `--help`, validate environment variables like `$OMARCHY_PATH`, and execute the requested operations.

```bash

# Example from a concrete command script (bin/omarchy-theme-set)

#!/usr/bin/env bash

while [[ $# -gt 0 ]]; do

    case $1 in
        --name)
            theme_name="$2"
            shift 2
            ;;
        --help)
            echo "Usage: omarchy theme set --name <theme>"
            exit 0
            ;;
        *)
            echo "Unknown flag: $1" >&2
            exit 1
            ;;
    esac
done

# Execute theme setting logic...

```

## Practical Usage Examples

The two-pass system becomes transparent during daily usage, but understanding the dispatch flow helps when debugging or extending the CLI.

**Setting a theme:**

```bash
$ omarchy theme set --name dark

```

The router resolves `theme set` to `bin/omarchy-theme-set`, then the second pass executes that script with `--name dark` as arguments.

**Toggling a feature:**

```bash
$ omarchy toggle nightlight --on

```

Here, `toggle` is the group, `nightlight` is the sub-command, mapped to `bin/omarchy-toggle-nightlight`, which receives `--on` in the second pass.

**Handling help requests:**

```bash
$ omarchy theme --help

```

When the router detects only a group without a valid sub-command, it executes `bin/omarchy-help` instead, displaying group-specific usage information.

## Benefits of the Two-Pass Architecture

This dispatch model provides several architectural advantages for the Omarchy project:

- **Separation of concerns**: The router only manages command-to-script mapping via `GROUP_DESCRIPTIONS`, while concrete scripts handle all option-level logic and validation.
- **Extensibility**: Adding new commands requires only creating a new `bin/omarchy-<group>-<cmd>` file and optionally updating the description map; the router itself remains unchanged.
- **Consistent error handling**: Invalid commands are caught in the first pass before any script execution begins, ensuring uniform error messaging across the CLI.

## Summary

- Omarchy’s CLI router in `bin/omarchy` implements **two-pass dispatch resolution** to handle command routing.
- **First pass**: Extracts group and sub-command, validates against `GROUP_DESCRIPTIONS`, and constructs the path to `bin/omarchy-<group>-<cmd>`.
- **Second pass**: Uses `exec` to replace the router process with the concrete script, passing remaining arguments for independent parsing.
- Concrete scripts reside in the `bin/` directory and handle their own flags, environment validation, and execution logic.
- This architecture enables modular command development with minimal coupling between the router and command implementations.

## Frequently Asked Questions

### What is two-pass dispatch resolution in Omarchy?

Two-pass dispatch resolution is the routing mechanism where the first pass identifies the correct command script based on group and sub-command, and the second pass executes that script with user-provided arguments. This separation allows the router to handle command lookup while delegating argument parsing to individual scripts.

### How does Omarchy map commands to scripts?

Omarchy uses the `GROUP_DESCRIPTIONS` associative array in `bin/omarchy` to recognize valid command groups, then constructs script names using the pattern `bin/omarchy-${group}-${subcmd}`. If the constructed path is executable, the router dispatches to it; otherwise, it falls back to the help command.

### Why does Omarchy use a two-pass system instead of a single pass?

The two-pass system enforces a strict separation between routing logic and command implementation, allowing developers to add new commands by simply creating executable scripts in the `bin/` directory without modifying the router code. It also ensures that argument parsing errors occur within the context of the specific command rather than the generic router.

### Where are the concrete command scripts located in the Omarchy repository?

Concrete command scripts follow the naming convention `bin/omarchy-<group>-<cmd>` and reside in the repository’s `bin/` directory alongside the main `omarchy` router script. For example, the theme set command is implemented in `bin/omarchy-theme-set`.