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
formatandformatAltparameters - The weather module accepts
locationandunitssettings - 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 objectBarModel.moduleString(entry): Determines the module type from themodulekeyBarModel.customModuleType(entry): Resolves the type for custom module declarationsBarModel.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.jsonwithout creating separate plugin files. - Add entries to the
left,center, orrightarrays with amodulefield specifying the widget type. - Configure options inline at the root level of the entry object;
BarModel.entrySettingshandles extraction automatically. - Use
customModulewithtypefor bespoke widgets not included in the core distribution. - The parsing logic in
shell/plugins/bar/Bar.qml(lines 350-380) andBarModelhelpers 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →