# How Omarchy Configures Web App Handlers: A Complete Technical Breakdown

> Discover how Omarchy configures web app handlers using XDG desktop entries Bash wrappers and JSON-C menus for seamless install launch and remove workflows. Get the technical breakdown.

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

---

**Web app handlers in Omarchy are configured through a three-layer system involving XDG desktop entries, thin Bash wrapper binaries, and a JSON-C menu definition that orchestrates install, launch, and remove workflows.**

This guide explores the complete configuration architecture for web app handlers in Omarchy, the open-source desktop environment from 37signals (basecamp/omarchy). You'll learn how the system registers web applications as first-class citizens, routes URLs through dedicated handlers, and manages their lifecycle through the Omarchy menu system.

## The Three Components of Web App Handler Configuration

Omarchy splits web app handler configuration across three interconnected components. Understanding the relationship between these layers is essential for customizing or debugging web app behavior.

| Component | Purpose | Location in Repository |
|-----------|---------|------------------------|
| **Desktop entries** | Register apps with XDG and point to handler binaries | `applications/*.desktop` |
| **Handler binaries** | Thin wrappers that receive URLs and forward to the menu system | `bin/omarchy-webapp-handler-<name>` |
| **Menu configuration** | Defines install/remove actions and discovery logic | `default/omarchy/omarchy-menu.jsonc` |

## Desktop Entries: The XDG Integration Layer

Desktop entries are standard `.desktop` files that integrate web apps into the Linux desktop environment. In Omarchy, these files live in the `applications/` directory and use a specific `Exec=` pattern.

### Anatomy of a Web App Desktop Entry

The `applications/HEY.desktop` file demonstrates the standard structure:

```ini
[Desktop Entry]
Name=Hey
Exec=omarchy-webapp-handler-hey %u
MimeType=x-scheme-handler/mailto
Type=Application

```

Key characteristics of Omarchy web app desktop entries:

- **Exec line** — Must contain `omarchy-webapp-handler-<name>` followed by `%u` to receive the URL
- **MIME type registration** — Uses `x-scheme-handler/<name>` for custom URL scheme handling
- **Naming convention** — Handler name matches the desktop entry name in lowercase

## Handler Binaries: The URL Routing Layer

Handler binaries are minimal Bash scripts located in `bin/` that bridge XDG desktop integration with Omarchy's internal menu system.

### Handler Script Structure

The `bin/omarchy-webapp-handler-hey` script exemplifies the pattern:

```bash
#!/usr/bin/env bash

# bin/omarchy-webapp-handler-hey

url="$1"

# Forward to the Omarchy launcher that knows how to open the URL

omarchy-launch-webapp "$url"

```

Design principles of handler binaries:

- **Single argument** — Receives the URL via `$1` (the `%u` placeholder in the desktop entry)
- **No logic here** — Handlers are intentionally thin; URL handling decisions live in `omarchy-launch-webapp`
- **Naming consistency** — Binary name suffix matches the desktop entry and URL scheme

## Menu Configuration: The Orchestration Layer

The `default/omarchy/omarchy-menu.jsonc` file defines how Omarchy's UI presents web app management actions. This JSON-C configuration drives discovery, installation, and removal workflows.

### Web App Discovery Logic

The menu includes a `remove.webapp` entry with a `when` clause that discovers existing web apps:

```jsonc
// Simplified excerpt from omarchy-menu.jsonc
{
  "remove.webapp": {
    "when": "desktop_file_exec_contains('omarchy-launch-webapp') || desktop_file_exec_contains('omarchy-webapp-handler')"
  }
}

```

This discovery mechanism scans `~/.local/share/applications/*.desktop` for files whose `Exec` line contains either `omarchy-launch-webapp` or `omarchy-webapp-handler`, ensuring both legacy and current web app formats are detected.

### Menu Actions

| Action | Command | Purpose |
|--------|---------|---------|
| Install web app | `omarchy-webapp-install` | Creates new `.desktop` file with handler binary |
| Remove web app | `omarchy-webapp-remove` | Deletes discovered `.desktop` files |

## The Complete Web App Lifecycle

### Installation Workflow

When a user selects **Install > Web App** from the Omarchy menu:

1. `omarchy-webapp-install` prompts for name, URL, and optional icon
2. Creates `.desktop` file in `~/.local/share/applications/`
3. Writes `Exec=omarchy-webapp-handler-<name> %u` line
4. Registers `x-scheme-handler/<name>` MIME type

### Launch Workflow

When a user clicks a web app icon or opens a matching URL scheme:

1. XDG system locates the `.desktop` file by MIME type or application name
2. Executes the handler binary with the URL as argument
3. Handler calls `omarchy-launch-webapp "$url"` to open in the default browser

### Removal Workflow

When a user selects **Remove > Web App** from the Omarchy menu:

1. `omarchy-webapp-remove` scans `~/.local/share/applications/*.desktop`
2. Matches files where `Exec` contains handler-related strings
3. Deletes matching entries and associated icons

## Practical Configuration Examples

### Creating a Custom Web App Handler

To add a new web app handler for a service like "Basecamp":

```bash

# Step 1: Create the handler binary

cat > bin/omarchy-webapp-handler-basecamp << 'EOF'
#!/usr/bin/env bash
url="$1"
omarchy-launch-webapp "$url"
EOF
chmod +x bin/omarchy-webapp-handler-basecamp

# Step 2: Create the desktop entry

cat > applications/Basecamp.desktop << 'EOF'
[Desktop Entry]
Name=Basecamp
Exec=omarchy-webapp-handler-basecamp %u
MimeType=x-scheme-handler/basecamp
Type=Application
EOF

```

### Inspecting Installed Web Apps

```bash

# Find all Omarchy-managed web apps on your system

grep -l "omarchy-webapp-handler\|omarchy-launch-webapp" \
  ~/.local/share/applications/*.desktop 2>/dev/null

```

## Key Source Files Reference

- **`applications/HEY.desktop`** — Reference desktop entry for web app integration: `https://github.com/basecamp/omarchy/blob/quattro/applications/HEY.desktop`

- **`bin/omarchy-webapp-handler-hey`** — Exemplar handler binary demonstrating URL forwarding: `https://github.com/basecamp/omarchy/blob/quattro/bin/omarchy-webapp-handler-hey`

- **`default/omarchy/omarchy-menu.jsonc`** — Menu configuration with web app discovery and action definitions: `https://github.com/basecamp/omarchy/blob/quattro/default/omarchy/omarchy-menu.jsonc`

## Summary

- Omarchy web app handler configuration uses a **three-layer architecture**: XDG desktop entries for system integration, thin Bash handler binaries for URL routing, and JSON-C menu configuration for UI orchestration.

- The **desktop entry** (`*.desktop` files) registers the app with `Exec=omarchy-webapp-handler-<name> %u` and defines the custom URL scheme via `MimeType`.

- The **handler binary** (`bin/omarchy-webapp-handler-*`) receives URLs from XDG and immediately forwards them to `omarchy-launch-webapp`, keeping all URL handling logic centralized.

- The **menu configuration** (`omarchy-menu.jsonc`) provides discovery logic and action commands (`omarchy-webapp-install`, `omarchy-webapp-remove`) that manage the web app lifecycle.

- All web app state lives in standard XDG directories (`~/.local/share/applications/`), making Omarchy-compliant with freedesktop specifications while adding its own opinionated conventions.

## Frequently Asked Questions

### How does Omarchy distinguish web apps from regular desktop applications?

Omarchy identifies web apps by scanning the `Exec=` line of `.desktop` files for the substrings `omarchy-webapp-handler` or `omarchy-launch-webapp`. This detection logic is implemented in the `when` clause of the `remove.webapp` menu entry in `omarchy-menu.jsonc`, not by file extension or directory location.

### Can I modify a handler binary to add custom URL processing logic?

Yes, though the design intentionally discourages it. According to the source code in `bin/omarchy-webapp-handler-hey`, handlers are minimal wrappers that delegate to `omarchy-launch-webapp`. Adding logic here would work for that specific app but fragments URL handling behavior. For system-wide changes, modify `omarchy-launch-webapp` itself.

### Where does Omarchy store user-installed web app desktop entries?

User-created web app desktop entries are written to `~/.local/share/applications/` by the `omarchy-webapp-install` command. System-wide web apps included with Omarchy reside in the repository's `applications/` directory. The removal workflow only scans the user directory, preventing accidental deletion of system components.

### What happens if the handler binary is missing for an installed web app?

The XDG system will attempt to launch the binary specified in the desktop entry's `Exec=` line. If `omarchy-webapp-handler-<name>` does not exist in `$PATH`, the launch fails silently in most desktop environments. Omarchy does not currently validate handler binary existence during the removal discovery process.