11 KiB
Style
- Two spaces for indentation, no tabs
- Use bash 5 conditionals: use
[[ ]]for string/file tests and(( ))for numeric tests - In
[[ ]], don't quote variables, but do quote string literals when comparing values (e.g.,[[ $branch == "dev" ]]) - Prefer
(( ))over numeric operators inside[[ ]](e.g.,(( count < 50 )), not[[ $count -lt 50 ]]) - For strings/paths with spaces, quote them instead of escaping spaces with
\(e.g.,"$APP_DIR/Disk Usage.desktop", not$APP_DIR/Disk\ Usage.desktop) - Shebangs must use
#!/bin/bashconsistently (never#!/usr/bin/env bash) - Scripts under
install/andmigrations/may be sourced and intentionally omit shebangs
Command Naming
All commands start with omarchy-. Prefixes indicate purpose.
The authoritative command group list lives in bin/omarchy in GROUP_DESCRIPTIONS. Keep GROUP_DESCRIPTIONS updated when adding a new command prefix.
Common prefixes include:
cmd-- check if commands exist, misc utility commandscapture-- screenshots, screen recordings, and other capture toolspkg-- package management helpershw-- hardware detection (return exit codes for use in conditionals)refresh-- copy default config to user's~/.config/restart-- restart a componentlaunch-- open applicationsinstall-- install optional softwaresetup-- interactive setup wizardstoggle-- toggle features on/offtheme-- theme managementupdate-- update components
Other current prefixes include:
ac-,audio-,battery-,branch-,brightness-,channel-,config-,debug-,dev-,drive-,first-,font-,haptic-,hibernation-,hook-,hyprland-,menu-,migrate-,notification-,npm-,plymouth-,powerprofiles-,reinstall-,remove-,screensaver-,show-,snapshot-,state-,sudo-,system-,transcode-,tui-,tz-,upload-,version-,voxtype-,webapp-,wifi-,windows-
Command Metadata
Commands in bin/ can declare CLI metadata in comments near the top of the file. bin/omarchy scans the first 80 lines, and tests expect command metadata to remain valid.
Supported metadata keys:
# omarchy:summary=...- short help text# omarchy:args=...- usage arguments# omarchy:examples=...- examples separated with|# omarchy:alias=.../# omarchy:aliases=...- alternate routes# omarchy:hidden=true- hide from default command listings# omarchy:requires-sudo=true- mark commands that require sudo
Only use omarchy:examples where there are args that need explaining.
Prefer explicit metadata for user-facing commands. Keep routes consistent with the filename unless there is a deliberate alias or compatibility route.
Example:
# omarchy:summary=Take a screenshot
# omarchy:args=[smart|region|windows|fullscreen] [slurp|copy]
# omarchy:examples=omarchy screenshot | omarchy capture screenshot region
Runtime Environment
$OMARCHY_PATHis set at the top level by the uwsm session environment and is always available to Omarchy runtime code.- Commands in
bin/and Quickshell QML should rely on$OMARCHY_PATH/Quickshell.env("OMARCHY_PATH"); do not derive fallback paths fromHOME,Quickshell.shellDir, or re-export/defaultOMARCHY_PATHmanually.
Privileged Commands
- Whenever you need to trigger a sudo command, use
pkexecso it results in a user prompt they can approve.
Git
- Commits should be atomic: include only one coherent change or fix, and do not mix unrelated work.
- Commit messages should be succinct and describe the change being made.
Install Scripts
The ISO owns installation orchestration. This repo ships target-side setup commands and reusable setup leaves:
bin/omarchy-setup-systemruns root-owned system setup during ISO finalization.bin/omarchy-setup-hardwareruns idempotent hardware-specific setup and is called byomarchy-setup-system.bin/omarchy-finalize-userruns the per-user runtime finalization (skill symlinks, xdg-user-dirs, mime defaults,install/user/all.sh). Shipped user defaults are seeded by/etc/skelfromomarchy-settings, not by this command.bin/omarchy-reinstall-configsis the explicit destructive resync of those defaults into an existing user's$HOME.- leaf scripts under
install/are sourced byrun_logged $OMARCHY_INSTALL/path/to/script.shand intentionally do not have shebangs. - avoid
exitin sourced setup scripts unless intentionally aborting setup. - use
$OMARCHY_INSTALLand$OMARCHY_PATHinstead of hard-coded Omarchy paths. - keep root-scoped hardware setup under
install/hardware/and orchestrate it throughinstall/hardware/all.sh. - keep every per-user setup leaf under
install/user/(includinginstall/user/hardware/andinstall/user/first-run/) so it is clear what must run for each user. - prefer helper commands for package and command checks where available.
Raw command -v, pacman, and pacman-key are acceptable in package-helper contexts where direct package-manager behavior is the point of the script.
Helper Commands
Use these instead of raw shell commands:
omarchy-cmd-missing/omarchy-cmd-present- check for commandsomarchy-pkg-missing/omarchy-pkg-present- check for packages (don't use these if you can just useomarchy-pkg-add/omarchy-pkg-drop)omarchy-pkg-add- install packages (handles both pacman and AUR)omarchy-pkg-drop- remove packages; use this instead of rawpacman -R*omarchy-notification-send- send desktop notifications; do not callnotify-senddirectlyomarchy-hw-asus-rog- detect ASUS ROG hardware (and similarhw-*commands)
Exceptions are allowed for migration and package-helper scripts where the helper may not be available yet, where the helper itself is being implemented, or where direct package-manager behavior is required.
Config Structure
config/- default configs copied to~/.config/default/themed/*.tpl- templates with{{ variable }}placeholders for theme colorsthemes/*/colors.toml- theme color definitions (accent, background, foreground, red/green/yellow/blue/magenta/cyan and bright_* variants)
Tests
Run focused automated tests for the area you changed. Current test entry points:
./test/all- aggregate runner for CLI and shell tests./test/cli- CLI routing, command metadata, theme helpers, and safe dispatch coverage./test/shell- all Omarchy shell tests undertest/shell.d/
New Omarchy shell tests should live in test/shell.d/*-test.sh so ./test/shell picks them up automatically. Source test/shell.d/base-test.sh for shared root-path discovery, assertions, and Node test helpers.
For visual changes, such as omarchy-shell styling, desktop appearance, screenshots, or screen recording flows, verify with the running UI in addition to automated tests. Take and analyze screenshots with omarchy capture screenshot fullscreen save. For animation, transitions, capture, or screen recording behavior, make a short recording with omarchy screenrecord --fullscreen, stop it with omarchy screenrecord --stop-recording, and review the output before finishing.
For interactive UI work, use wtype to simulate keyboard input when available. Example: start the UI in the background, wait briefly for focus, then run wtype -k Right -k Return to exercise keyboard selection and confirm the resulting command output or state change. Prefer this over manual-only verification when a UI returns a selected value or changes a symlink/config.
When testing layer-shell UI, capture the reference and candidate states as separate screenshots, then compare them visually before further edits. If a launched UI would otherwise remain open, keep track of its PID and stop it after the screenshot; avoid broad process kills unless checking with ps first.
Omarchy shell
The Quickshell desktop runs as a single long-running process out of
shell/. Hyprland autostart launches it directly with quickshell -p; do
not start additional standalone quickshell -p instances for individual
components.
Run omarchy-restart-shell after making changes to QML files.
Plugin contract:
- Each plugin lives in its own directory under
shell/plugins/<id>/(first-party) or~/.config/omarchy/plugins/<id>/(third-party). - Every plugin ships a
manifest.jsondeclaringid,kinds,activation, andentryPoints. The full schema is indocs/omarchy-shell.md. - Entry-point QML files are
Items (notShellRoot), and accept the shell-injected propertiesomarchyPath,shell,manifest, andpluginRegistry/barWidgetRegistryas appropriate. - Panel / overlay / menu plugins must expose
open(payloadJson)andclose()lifecycle methods forshell summonandshell hide.
IPC:
bin/omarchy-shellis the canonical IPC entry point. It forwards to the running shell and does not start it. Prefer it over re-implementing direct Quickshell socket calls in every CLI.- The
shellIPC target exposesping,summon,hide,toggle,rescanPlugins,setPluginEnabled, andlistPlugins. Individual plugins can register additional IPC targets (the bar registersbar, the background switcher registersimage-selector).
Widget files in shell/plugins/bar/widgets/ contain Nerd Font glyphs as raw
unicode characters. The Write and Edit tools strip multi-byte
codepoints in some positions — do not rewrite widget files wholesale
through those tools. For glyph fixes, use the targeted Edit tool with
the surrounding context, or a Python script that inserts codepoints via
chr(0xXXXXX).
Refresh Pattern
To copy a default config to user config with automatic backup:
omarchy-refresh-config hypr/hyprlock.conf
This copies /etc/skel/.config/hypr/hyprlock.conf to ~/.config/hypr/hyprlock.conf.
Migrations
Read docs/migrations.md before creating or changing migrations.
Migrations are split by execution scope:
migrations/system/<timestamp>.sh— root, noninteractive, safe to run from pacman viaomarchy-migrate-system(omarchypost_upgradecalls it). Use for/etc,/usr,/boot, services, hardware quirks, and other system state. Do not prompt.migrations/user/<timestamp>.sh— current user/session, may touch~/.config,~/.local, user systemd, browser prefs, DBus/session state, and may prompt if necessary. Runs throughomarchy-migrate/omarchy-migrate-user; pending state is per-user based on missing files under~/.local/state/omarchy/migrations/user/.
To create a new migration, run omarchy-dev-add-migration system --no-edit or omarchy-dev-add-migration user --no-edit based on scope.
New migration format:
- File permissions must be
0644(-rw-r--r--); migration runners execute them withbash -euo pipefail, not through executable bits - No shebang line
- Start with an
echodescribing what the migration does - Use
$OMARCHY_PATHto reference the omarchy directory - Prefer helper commands such as
omarchy-cmd-present,omarchy-cmd-missing,omarchy-pkg-present, andomarchy-pkg-missing
Omarchy 4.0 is upgraded through bin/omarchy-upgrade-to-4, not through the normal migration runner. Do not add compatibility migrations for old installer layouts; put pre-4 package-layout transition work in the upgrade command instead.
Migrations may use raw pacman, command -v, or direct config edits when needed for one-off repair work.