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

You can create inline bar modules in Omarchy by declaring widget entries directly in your 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 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.

{
  "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.

{
  "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.

// ~/.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:

{
  "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 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 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →