Development Guidelines for Omarchy: Contributing to the Arch-Based Desktop Environment
Development guidelines for Omarchy require following a strict repository layout with runtime binaries in bin/, system defaults in default/, user configs in config/, and migrations in migrations/, alongside Bash 5 scripting standards, idempotent migration scripts, and comprehensive testing via ./test/all.
Omarchy is a tightly-integrated Arch-based desktop environment maintained by Basecamp that combines runtime packages, user-land configuration, and a Quickshell desktop. Understanding the development guidelines for Omarchy is essential before contributing code, as the project enforces specific architectural boundaries between system-wide defaults and per-user state. This guide covers the repository structure, coding conventions, testing requirements, and contribution workflow based on the actual source code implementation.
Repository Layout and File Architecture
The architecture is documented in docs/file-layout.md. The repository organizes code into distinct layers that map to specific filesystem locations upon installation.
Source-to-Install Mapping
| Layer | Source Tree | Install Target |
|---|---|---|
| Runtime binaries | bin/ |
/usr/bin/omarchy-* |
| System-wide defaults | default/ |
/usr/share/omarchy/default/ (plus /etc/skel/ seeds) |
| User-side config | config/ |
~/.config/omarchy/ (seeded from /etc/skel/) |
| Migrations | migrations/ |
~/.local/state/omarchy/migrations/ |
| Shell plugins | shell/ |
/usr/share/omarchy/shell/ |
| Documentation | docs/, manual/ |
Rendered on the website |
When adding new files, adhere to this rule: system-wide resources belong in default/, while per-user configuration must live in config/ or be handled via the migrations/ system.
Coding Standards and Conventions
Bash Scripting Requirements
All shell scripts in the Omarchy repository must conform to Bash 5 standards. According to the Shell-Dev Skill Guide at agents/skills/shell-dev.md, scripts must:
- Use
set -euo pipefailto enable strict error handling - Use
[[ … ]]for string comparisons and(( … ))for numeric operations - Target Bash 5 syntax exclusively
Quickshell Plugin Development
Plugins for the Quickshell desktop are written in JavaScript and stored in shell/plugins/. Each module must export its logic using module.exports = … to enable unit testing with Node. This architecture allows the test harness to load and validate plugin logic outside the graphical environment.
Example plugin structure:
// shell/plugins/example/ExamplePlugin.js
const { registerPlugin } = require('omarchy-plugin-utils');
function init() {
// Plugin logic here
}
if (typeof module !== 'undefined') {
module.exports = { init };
}
registerPlugin('example', init);
CLI Command Naming
All user-facing commands must follow the omarchy- prefix convention and be placed in the bin/ directory. The central dispatcher at bin/omarchy maintains a GROUP_DESCRIPTIONS array that automatically categorizes commands in the help router. Include metadata comments in new scripts:
#!/usr/bin/env bash
# omarchy:summary=Show a friendly greeting
# omarchy:group=demo
set -euo pipefail
echo "Hello from omarchy-foo-bar!"
Commit and Documentation Standards
Follow the atomic commit guidelines in AGENTS.md: one coherent change per commit. Documentation updates must accompany code changes, with user-facing guides in manual/ and developer documentation in docs/.
Testing Strategy and CLI Validation
The test suite runs via ./test/all and supports multiple test types:
- CLI tests: Validate routing, metadata extraction, and theme pipelines
- Shell tests: Located in
test/shell.d/, one file per feature, each sourcingbase-test.sh - Node tests: Execute JavaScript modules using
run_node_testfor Quickshell plugins
All shell test files must begin with this boilerplate:
#!/usr/bin/env bash
set -euo pipefail
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"
require_command omarchy
pass "omarchy command is present"
Tests should create temporary bin/ directories containing mock executables to log arguments, ensuring the suite remains hermetic and CI-friendly. Full details are available in docs/testing.md.
Migration Model for User State
Changes affecting per-user state after initial installation must be implemented as idempotent migration scripts in migrations/. These scripts:
- Execute as the user via
omarchy-migrate - Store completion markers in
~/.local/state/omarchy/migrations/ - Must be safe to run multiple times
Example migration structure:
#!/usr/bin/env bash
# 2025-03-01-add-example-config.sh
set -euo pipefail
SRC="$OMARCHY_PATH/config/example.conf"
DEST="${HOME}/.config/omarchy/example.conf"
[[ ! -e "$DEST" ]] && cp -a "$SRC" "$DEST"
See agents/skills/migrations.md for the complete authoring checklist.
Contribution Workflow
To contribute to Omarchy:
- Fork the repository:
gh repo fork basecamp/omarchy --clone - Create a descriptive branch name
- Place files according to the architecture (runtime in
bin/, configs inconfig/ordefault/) - Run the full test suite:
./test/all - Open a PR following
AGENTS.mdguidelines
For local development, use omarchy dev link to create a live symlink tree, allowing you to test changes without reinstalling the package. The Development Tools manual at manual/18-development-tools.md documents additional runtimes and helper scripts.
Summary
- Repository Layout: Respect the boundary between
bin/(runtime),default/(system-wide),config/(user), andmigrations/(state updates) - Coding Standards: Write Bash 5 with
set -euo pipefail, export JavaScript modules for testability, and prefix commands withomarchy- - Testing: Validate changes via
./test/all, with shell tests intest/shell.d/and Node tests for Quickshell plugins - Migrations: Implement per-user changes as idempotent scripts in
migrations/that mark completion in~/.local/state/omarchy/migrations/ - Workflow: Fork, branch, test, and PR following
AGENTS.md, usingomarchy dev linkfor local testing
Frequently Asked Questions
What directory should I use for new configuration files?
Place system-wide defaults in default/ (installs to /usr/share/omarchy/default/ and seeds /etc/skel/), but put per-user configuration templates in config/ (installs to ~/.config/omarchy/). If you need to update existing user installations, create a migration script in migrations/ instead.
How do I test JavaScript Quickshell plugins?
Export your plugin logic using module.exports = … at the end of the JavaScript file, then use the run_node_test helper from the bash test suite. The Node bridge loads the module in a Node environment to validate logic without launching the graphical desktop.
Why must migration scripts be idempotent?
Migration scripts run every time omarchy-migrate executes and store completion markers in ~/.local/state/omarchy/migrations/. They must be idempotent because users may trigger migrations multiple times, and the script should safely skip already-applied changes without error.
Where are the authoritative style and commit guidelines documented?
The AGENTS.md file at the repository root contains the definitive rules for commit message format, atomic commit size, and pull request standards. All contributors must follow these conventions to maintain project coherence.
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 →