This is the post-install checklist I use to turn a fresh Omarchy system into my everyday workstation. The values and package choices reflect my hardware and workflow, so review each section before applying it to your own system.
System configuration
DNS
Select Setup -> DNS -> Cloudflare from the Omarchy menu.
Confirm the active DNS configuration with:
resolvectl status
Shell aliases and PATH
Add these aliases and environment variables:
# CUSTOM
# non-omarchy alias for real ls
# alias la="ls -lahF"
# omarchy alias for replaced-by-eza ls
alias la="ls -lah --classify=auto"
export PATH=~/bin:$PATH
export ERL_AFLAGS="-kernel shell_history enabled"
Waybar
I keep all ten workspaces visible, add detail to the clock, and show the active network interface:
{
// ...
"persistent-workspaces": {
"1": [],
"2": [],
"3": [],
"4": [],
"5": [],
"6": [],
"7": [],
"8": [],
"9": [],
"10": []
},
// ...
"clock": {
"interval": 1,
"format": "☀️ {:L%A w%V 📅 %Y / %m / %d 🕑 %H:%M:%S}",
// ...
},
// ...
"network": {
// ...
"format-wifi": "{icon} {ipaddr} ({ifname})",
"format-ethernet": " {ipaddr} ({ifname})",
// ...
}
}
Restart Waybar to apply the changes immediately:
omarchy restart waybar
Enable fstrim for an encrypted SSD
Run a manual trim check:
sudo fstrim / -v
If it returns fstrim: /: the discard operation is not supported, add :allow-discards immediately after some-id:root:
KERNEL_CMDLINE[default]="cryptdevice=PARTUUID=some-large-uuid:root:allow-discards ...
Regenerate the Limine configuration after saving the file:
sudo limine-update
Then enable the periodic trim timer:
sudo systemctl enable --now fstrim.timer
Restart the system to apply the kernel command-line change.
Software
Restore your backup
Remount the encrypted partition , then restore the files from your full-disk-encrypted backup drive.
Remove software I do not use
The following command removes packages that are not part of my workflow. Review the list before running it, especially on a system you have already configured:
sudo pacman -Rns 1password-cli 1password-beta \
signal-desktop spotify xournalpp claude-code \
docker docker-buildx docker-compose ufw-docker lazydocker
Remove each unused web app through:
Omarchy menu -> Remove -> Web App
If I want to clear ~/.local/bin, I inspect it first because the removal command targets every non-hidden entry there, not only npm-installed commands:
ls -la ~/.local/bin
rm ~/.local/bin/*
Update the system
omarchy update
Install desktop and command-line software
This is the software I typically need on a workstation:
sudo pacman -S nethogs transmission-gtk nmap \
darktable gimp inkscape krita godot \
blender calibre obs-studio shotcut \
colordiff python-gobject python-xdg yt-dlp \
qgis python-gdal python-owslib python-psycopg2 python-pygments \
ansible inotify-tools jq \
simple-scan audacity base-devel \
libvips openslide firefox iotop \
vlc vlc-plugins-base vlc-plugins-extra \
podman pass
yt-dlp
If the normal extractor cannot download a video, try the generic extractor:
yt-dlp --force-generic-extractor URL
# or install python-curl_cffi
Install Erlang, Elixir, Node.js, and Go with mise
List the language runtimes already installed:
mise ls
Choose and install an Erlang version:
mise ls-remote erlang
# pick a version you want, for example:
mise use erlang@29.0.1 --global
Choose an Elixir build that matches the installed Erlang/OTP version, then install the Hex, Rebar, Phoenix, and Nerves tooling:
mise ls-remote elixir
# pick a version you want, for example:
mise use elixir@1.20.0-otp-29 --global
mix local.hex
mix local.rebar
mix archive.install hex phx_new
mix archive.install hex nerves_bootstrap
Choose and install a Node.js version, then install the npm and pnpm tools:
mise ls-remote node
# pick a version you want, for example:
mise use node@26.3.0 --global
npm i -g npm
npm i -g pnpm
pnpm setup
Set a minimum package release age so newly published versions are not installed immediately:
# pnpm in minutes
pnpm config set minimumReleaseAge 2880
# npm in days
npm config set min-release-age 2 --location=global
Choose and install a Go version:
mise ls-remote go
# pick a version you want, for example:
mise use go@1.26.4 --global
Install PostgreSQL
sudo pacman -S postgresql postgresql-libs postgis
sudo -i -u postgres
initdb --locale $LANG -E UTF8 -D '/var/lib/postgres/data/'
exit
Enable PostgreSQL now and on future system starts:
sudo systemctl enable --now postgresql.service
Workstation fixes and desktop settings
Prevent Bluetooth audio lag after inactivity
Disable WirePlumber's node suspension:
wireplumber.profiles = {
main = {
hooks.node.suspend = disabled
}
}
Then restart the audio services:
systemctl --user restart wireplumber.service pipewire.service
Make Shift+Enter work in tmux and Alacritty
If Alacritty does not forward Shift+Enter inside a tmux session - for example, when adding a new line to a Pi prompt - add this binding:
[keyboard]
bindings = [
#...
{ key = "Return", mods = "Shift", chars = "\u001b[13;2u" }
]
Install GPU utilities
For NVIDIA:
sudo pacman -S nvtop nvidia-utils
For AMD:
sudo pacman -S vulkan-radeon
Code editor
Zed
Install -> Editor -> Zed
Extensions:
- Catppuccin
- Catppuccin Icons
- Dockerfile
- Elixir
- Emmet
- Git Firefly
- HTML
- Rainbow CSV
- SCSS & SASS
- SQL
- TOML
- Vue
- Zig
If Ctrl+Enter opens the assistant panel instead of inserting a cursor on the next line, add these bindings:
[
//...
{
"context": "Editor && mode == full",
"bindings": {
"ctrl-enter": "editor::NewlineBelow",
"ctrl-shift-enter": "editor::NewlineAbove",
},
},
]
My Zed settings:
{
"autosave": "on_window_change",
"buffer_font_size": 12,
"buffer_line_height": "comfortable",
"cursor_blink": true,
"cursor_shape": "bar",
"file_finder": { "modal_max_width": "large" },
"file_types": {
"HTML": ["*.svg"],
},
"icon_theme": "Catppuccin Mocha",
"indent_guides": {
"coloring": "indent_aware",
},
"languages": {
"CSS": {
"language_servers": [
"tailwindcss-intellisense-css",
"!vscode-css-language-server",
"...",
],
},
"Elixir": {
"language_servers": [
"expert",
"tailwindcss-language-server",
"emmet-language-server",
"!elixir-ls",
"!next-ls",
"!lexical",
"...",
],
},
"HEEx": {
"language_servers": [
"expert",
"tailwindcss-language-server",
"emmet-language-server",
"!elixir-ls",
"!next-ls",
"!lexical",
"...",
],
},
},
"prettier": {
// "plugins": ["prettier-plugin-tailwindcss"],
"semi": false,
"singleQuote": false,
},
// "lsp": {
// "vscode-css-language-server": {
// "settings": {
// "css": {
// "lint": {
// "unknownAtRules": "ignore",
// },
// },
// },
// },
// },
"show_whitespaces": "all",
"soft_wrap": "editor_width",
"ui_font_size": 14,
"tab_size": 2,
"tabs": {
"file_icons": true,
},
"theme": {
"mode": "dark",
"light": "Catppuccin Latte",
"dark": "Catppuccin Mocha",
},
}
AI tools
Install OpenCode, Pi, and agent-browser with either pnpm or npm:
# with pnpm
pnpm add -g --allow-build=opencode-ai opencode-ai
pnpm add -g --ignore-scripts @earendil-works/pi-coding-agent
pnpm add -g agent-browser
# or with npm
npm install -g --allow-scripts=opencode-ai opencode-ai
npm install -g --ignore-scripts @earendil-works/pi-coding-agent
npm install -g agent-browser
Set OpenCode to notify before updating and keep optional MCP server configurations ready:
{
// ...
"autoupdate": "notify",
"default_agent": "plan",
// "mcp": {
// "chrome-devtools": {
// "type": "local",
// "command": ["npx", "chrome-devtools-mcp@latest", "--executablePath=/usr/bin/chromium", "--isolated=true"],
// "enabled": false
// },
// "context7": {
// "type": "local",
// "command": ["npx", "-y", "@upstash/context7-mcp@latest"]
// },
// "playwright": {
// "type": "local",
// "command": ["npx", "@playwright/mcp@latest", "--executable-path=/usr/bin/chromium"],
// "enabled": false
// }
// }
}
Fabric
Install Fabric from its repository, then run its setup flow:
# Install Fabric directly from the repo
go install github.com/danielmiessler/fabric/cmd/fabric@latest
# Configure your directories and keys
fabric --setup
Reset UFW
To discard the current UFW rules and enable a fresh firewall configuration:
sudo ufw reset
sudo ufw enable
Extend desktop idle timeouts
The default idle timeouts are too short for my desktop. I replace them with the following one-hour screensaver and lock sequence:
general {
lock_cmd = omarchy-system-lock # lock screen and 1password
before_sleep_cmd = OMARCHY_LOCK_ONLY=true omarchy-system-lock # lock before suspend without scheduling display off.
after_sleep_cmd = sleep 1 && omarchy-system-wake # delay for PAM readiness, then turn on display.
inhibit_sleep = 3 # wait until screen is locked
}
# Start screensaver after 1hr
listener {
timeout = 3600
on-timeout = pidof hyprlock || omarchy-launch-screensaver
}
# Lock after 1hr and 2s (the screensaver resets the idle timer, so add a 2s margin)
listener {
timeout = 3602
on-timeout = omarchy-system-lock
on-resume = omarchy-system-wake
}
Configure two desktop monitors
List the connected monitors and note their output names:
hyprctl monitors
My configuration assigns workspaces 1-5 to the landscape display and 6-10 to the rotated display:
# ...
# Comment everything above this...
# CUSTOM
monitor=HDMI-A-2,3840x2160@60,0x0,1.5
monitor=HDMI-A-1,3840x2160@60,2560x-720,1.5,transform,3
workspace=1,monitor:HDMI-A-2
workspace=2,monitor:HDMI-A-2
workspace=3,monitor:HDMI-A-2
workspace=4,monitor:HDMI-A-2
workspace=5,monitor:HDMI-A-2
workspace=6,monitor:HDMI-A-1
workspace=7,monitor:HDMI-A-1
workspace=8,monitor:HDMI-A-1
workspace=9,monitor:HDMI-A-1
workspace=10,monitor:HDMI-A-1
Add fonts
Place user-specific font files in ~/.local/share/fonts.
Add laptop touchpad gestures
Add three-finger workspace and full-screen gestures:
gesture = 3, horizontal, workspace
gesture = 3, up, fullscreen
gestures {
workspace_swipe_invert = false
}
Reduce window gaps
Set smaller inner gaps and remove outer gaps:
general {
gaps_in = 2
gaps_out = 0
}
Hyprland reloads these files automatically after each save. Check the active configuration for errors after changing hypridle.conf, monitors.conf, input.conf, or looknfeel.conf:
hyprctl reload
hyprctl configerrors