# How to Create Inline Bar Modules in Omarchy: A Complete Configuration Guide

> Learn to create inline bar modules in Omarchy by configuring widget entries directly in bar.json. This guide simplifies widget instantiation without separate plugin files.

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

---

**You can create inline bar modules in Omarchy by declaring widget entries directly in your [`bar.json`](https://github.com/basecamp/omarchy/blob/main/bar.json) configuration file with a `module` field, allowing the `BarModel` parser to instantiate widgets on-the-fly without loading separate plugin files.**

Omarchy, the open-source desktop environment maintained by Basecamp, implements its top-bar using a JSON-style layout system that supports lightweight, one-off widgets. These **inline bar modules** let you define widgets directly within the bar configuration arrays rather than creating standalone plugin files. This architecture, handled by the `BarModel` helpers in `shell/plugins/bar/Bar.qml`, streamlines customization while keeping your configuration compact and maintainable.

## Understanding the Bar Layout Structure

Omarchy’s top-bar organizes widgets into three positional arrays within your configuration: `left`, `center`, and `right`. Each array accepts entry objects that can either reference external plugins or define **inline modules** directly.

When the bar renders, the logic in `shell/plugins/bar/Bar.qml` (specifically around lines 350-380) delegates parsing to `BarModel` functions. The helper `BarModel.entrySettings` extracts configuration options, while `BarModel.moduleString` identifies the module type from the entry object. If the entry contains a `module` key, `BarModel` creates the widget immediately without requiring a separate plugin file lookup.

## Configuration File Location

Your bar configuration resides at `~/.config/omarchy/bar.json`. This JSON file contains three top-level arrays that correspond to the physical layout of the screen:

- **left**: Widgets aligned to the left side of the bar
- **center**: Widgets centered in the bar
- **right**: Widgets aligned to the right side of the bar

Each array accepts objects that define either traditional plugin references or inline module declarations.

## Step-by-Step: Creating an Inline Module

To create an inline bar module, you add a properly structured entry to any of the three layout arrays in your [`bar.json`](https://github.com/basecamp/omarchy/blob/main/bar.json) file.

### 1. Define the Entry Object

Create an object with a unique `id` field and place it in the appropriate array. The `id` serves as the widget identifier within the bar system.

```json
{
  "left": [
    { "id": "omarchy.clock" }
  ]
}

```

### 2. Specify the Module Type Inline

Add a `module` field to the entry object to declare the widget type. This field tells `BarModel.moduleString` which built-in widget constructor to invoke.

```json
{
  "left": [
    { "id": "omarchy.clock", "module": "clock" }
  ]
}

```

### 3. Configure Module Options

Add configuration parameters directly to the same entry object. Unlike external plugins that may require nested `config` objects, inline modules accept options at the root level of the entry. The `BarModel.entrySettings` function extracts these keys and passes them to the widget constructor.

```json
// ~/.config/omarchy/bar.json
{
  "left": [
    {
      "id": "omarchy.clock",
      "module": "clock",
      "format": "HH:mm",
      "formatAlt": "hh:mm a"
    }
  ],
  "center": [
    {
      "id": "omarchy.customWeather",
      "module": "weather",
      "location": "San Francisco",
      "units": "imperial"
    }
  ],
  "right": [
    {
      "id": "omarchy.tray",
      "module": "tray"
    }
  ]
}

```

In this example:
- The **clock** module receives `format` and `formatAlt` parameters
- The **weather** module accepts `location` and `units` settings
- The **tray** module uses default configuration with no additional options

## Creating Custom Inline Modules

For widgets not included in Omarchy’s built-in set, you can declare custom inline modules using the `customModule` field. This approach leverages `BarModel.customModuleType` and `BarModel.customModulePath` to resolve your JavaScript implementation on-demand.

Provide a `type` field alongside your `customModule` declaration, plus any custom options your implementation requires:

```json
{
  "right": [
    {
      "id": "omarchy.myWidget",
      "customModule": true,
      "type": "myCustomType",
      "refreshInterval": 5000,
      "apiEndpoint": "https://api.example.com/data"
    }
  ]
}

```

When the bar parses this entry, `BarModel.customModuleType` identifies the module classification while `BarModel.customModulePath` resolves the file location, loading your JavaScript without requiring a formal plugin registration.

## How Inline Parsing Works

The inline module system relies on specific helper functions within the `BarModel` component imported by `shell/plugins/bar/Bar.qml`:

- **`BarModel.entrySettings(entry)`**: Extracts all configuration options from the entry object
- **`BarModel.moduleString(entry)`**: Determines the module type from the `module` key
- **`BarModel.customModuleType(entry)`**: Resolves the type for custom module declarations
- **`BarModel.customModulePath(entry)`**: Calculates the filesystem path for custom JavaScript files

As documented in [`docs/omarchy-shell.md`](https://github.com/basecamp/omarchy/blob/main/docs/omarchy-shell.md) under the section *“One-off inline modules”*, this parsing occurs during bar initialization. The system creates widgets on-the-fly based on the inline definitions, eliminating the overhead of separate plugin file loading for simple use cases.

## Summary

- **Inline bar modules** let you declare widgets directly in `~/.config/omarchy/bar.json` without creating separate plugin files.
- Add entries to the `left`, `center`, or `right` arrays with a `module` field specifying the widget type.
- Configure options inline at the root level of the entry object; `BarModel.entrySettings` handles extraction automatically.
- Use `customModule` with `type` for bespoke widgets not included in the core distribution.
- The parsing logic in `shell/plugins/bar/Bar.qml` (lines 350-380) and `BarModel` helpers instantiates widgets on-the-fly based on your JSON configuration.

## Frequently Asked Questions

### What is the difference between inline modules and separate plugins?

Inline modules require no separate file creation—you declare them directly in your [`bar.json`](https://github.com/basecamp/omarchy/blob/main/bar.json) configuration. Separate plugins reside in distinct directories with their own manifest files and are loaded as standalone units. Inline modules suit simple, one-off widgets, while separate plugins better serve complex, reusable components requiring extensive logic or resources.

### Where is the bar configuration file located?

The configuration file is located at `~/.config/omarchy/bar.json`. This file contains the three layout arrays (`left`, `center`, `right`) where you define your inline module entries. Changes to this file take effect when the bar next reloads its configuration.

### Can I use custom JavaScript modules inline?

Yes. Specify `customModule: true` and provide a `type` field in your entry. `BarModel.customModuleType` and `BarModel.customModulePath` resolve your JavaScript file and load it on-demand. This allows you to prototype custom widgets without formal plugin packaging, though you must ensure your JavaScript file exists at the expected path.

### How do I debug inline module configuration errors?

Check the Omarchy shell logs for parsing errors from `BarModel`. If an inline module fails to appear, verify that the `module` field matches a known widget type and that all required options are present. For custom modules, confirm that `BarModel.customModulePath` can locate your JavaScript file and that the `type` field is correctly specified.