# How to Define Custom Bar Widgets Inline in Omarchy

> Learn how to define custom bar widgets in Omarchy. While inline configuration is possible for existing settings, new widget logic requires a separate Lua plugin file.

- Repository: [37signals/omarchy](https://github.com/basecamp/omarchy)
- Tags: how-to-guide
- Published: 2026-08-22

---

**You can configure existing widget settings inline in `~/.config/omarchy/shell.json`, but you cannot define new widget implementation logic inline—custom widgets require a separate Lua plugin file.**

Omarchy's top-bar system offers extensive customization through its JSON-based configuration, allowing users to tailor their desktop environment without touching core code. While you can rearrange and configure widgets directly in your configuration file, the architecture enforces a strict separation between layout configuration and widget logic. This guide explains how to work within these constraints to customize your Omarchy bar effectively.

## Understanding Omarchy's Bar Configuration System

The Omarchy bar is constructed from a list of widget IDs stored in `~/.config/omarchy/shell.json` under the `bar.layout` key. This JSON structure organizes widgets into three sections—`left`, `center`, and `right`—each containing an array of widget objects.

Each widget entry in the layout array can include inline configuration parameters. According to the Omarchy source code, supported inline settings include `format`, `formatAlt`, and widget-specific options that control display behavior. This design keeps the layout definition declarative while allowing granular configuration of individual widgets.

## Configuring Existing Widgets Inline

You can add, remove, reorder, and customize existing widgets entirely through inline configuration in [`shell.json`](https://github.com/basecamp/omarchy/blob/main/shell.json). Once a widget plugin is installed and enabled, you control its presence and behavior through the layout array.

### Adding a Widget with Inline Format Settings

Enable the widget using the CLI, then configure its display parameters directly in the JSON layout:

```bash

# Enable the widget (one-time setup)

omarchy plugin enable omarchy.media --section right

# Set inline formatting options

omarchy bar set omarchy.media format "%artist – %title"

```

The resulting entry in `~/.config/omarchy/shell.json` appears as:

```json
{
  "id": "omarchy.media",
  "format": "%artist – %title"
}

```

### Reordering Widgets Across Sections

Move widgets between sections or adjust their priority using the move command:

```bash
omarchy bar move omarchy.clock --section left --index 0

```

This updates the layout structure in [`shell.json`](https://github.com/basecamp/omarchy/blob/main/shell.json):

```json
{
  "layout": {
    "left": [
      { "id": "omarchy.clock", "format": "HH:mm" },
      { "id": "omarchy.menu" }
    ],
    "center": [],
    "right": []
  }
}

```

### Disabling Widgets Without Uninstalling

Remove a widget from the bar layout while preserving the plugin installation:

```bash
omarchy bar disable omarchy.weather

```

This command deletes the widget entry from the `bar.layout` array in `~/.config/omarchy/shell.json` without affecting the underlying plugin files.

## Creating New Widgets: The Plugin Requirement

**Defining brand-new widget logic inline is not supported.** The `bar.layout` array in [`shell.json`](https://github.com/basecamp/omarchy/blob/main/shell.json) accepts only widget IDs and configuration objects—it cannot execute Lua code or contain widget implementation details.

New widget logic must reside in a dedicated Lua script within the repository structure, typically under `default/hypr/apps/` or a designated custom plugin directory. This architecture ensures that custom code remains modular, testable, and isolated from configuration data.

## Step-by-Step: Building a Custom Bar Widget

To create a truly custom widget that you can then configure inline, you must implement the widget as a plugin first.

### 1. Implement the Widget Logic

Create a Lua file in the appropriate directory. For example, [`default/hypr/widgets/my-widget.lua`](https://github.com/basecamp/omarchy/blob/main/default/hypr/widgets/my-widget.lua):

```lua
local widget = {}
widget.id = "my.custom"
widget.render = function()
    return "⚡ Custom"
end
return widget

```

Reference the implementation pattern used in [`default/hypr/apps/omarchy-shell.lua`](https://github.com/basecamp/omarchy/blob/main/default/hypr/apps/omarchy-shell.lua) for the widget contract details, including required fields like `id` and `render` functions.

### 2. Enable the Plugin

Register your custom widget with the Omarchy system:

```bash
omarchy plugin enable my.custom --section right

```

### 3. Configure Inline

Once enabled, treat your custom widget like any built-in widget. Add it to `bar.layout` and set inline options:

```bash
omarchy bar set my.custom someOption true

```

The widget now appears in `~/.config/omarchy/shell.json` with your custom settings applied inline, while the implementation remains safely encapsulated in its Lua file.

## Summary

- **Inline configuration** in `~/.config/omarchy/shell.json` supports adding, removing, reordering, and parameterizing existing widgets through the `bar.layout` structure.
- **Configuration parameters** like `format` and `formatAlt` can be set directly in JSON for any enabled widget, including custom ones.
- **New widget implementations** require Lua plugin files located in `default/hypr/apps/` or custom plugin directories—inline Lua code in [`shell.json`](https://github.com/basecamp/omarchy/blob/main/shell.json) is not supported.
- **Enable custom plugins** using `omarchy plugin enable <widget-id>` before adding them to your bar layout for inline configuration.

## Frequently Asked Questions

### Can I write Lua widget code directly in my shell.json file?

No. The `bar.layout` array in `~/.config/omarchy/shell.json` accepts only widget IDs and configuration objects such as `format` or `formatAlt`. Widget implementation logic must reside in separate Lua files within the Omarchy repository structure, typically under `default/hypr/apps/` or a custom plugin directory, to maintain separation between configuration and code.

### How do I add a custom widget to my Omarchy bar after creating the Lua file?

First, enable the plugin using `omarchy plugin enable <widget-id> --section <left|center|right>`. Once registered, you can add the widget ID to your `bar.layout` array in `~/.config/omarchy/shell.json` or use CLI commands like `omarchy bar move` to position it. After placement, configure its inline options using `omarchy bar set <widget-id> <option> <value>`.

### Can I modify the display format of built-in widgets without creating plugins?

Yes. Built-in widgets such as `omarchy.media` and `omarchy.clock` support inline configuration through the `format` and `formatAlt` keys. Use the CLI command `omarchy bar set <widget-id> format "<pattern>"` to customize display strings directly in [`shell.json`](https://github.com/basecamp/omarchy/blob/main/shell.json) without modifying any source files.

### Where should I place custom widget Lua files in the Omarchy repository?

Place custom widget implementations in `default/hypr/apps/` or a dedicated custom plugin directory if configured in your environment. The file must export a widget table containing at least an `id` field and a `render` function, following the contract demonstrated in the [`omarchy-shell.lua`](https://github.com/basecamp/omarchy/blob/main/omarchy-shell.lua) source and validated by the bar widget contract test suite.