How Omarchy Populates User Home Directories: The Three-Stage Model

Omarchy populates user home directories through a three-stage pipeline—Seed, Finalize, and Resync—that separates initial skeleton copying from runtime configuration and optional destructive refresh cycles.

Omarchy’s approach to user directory initialization follows a deliberate, layered architecture designed to separate static defaults from dynamic, system-dependent configuration. Understanding how user home directories are populated in Omarchy requires examining the distinct phases defined in the docs/file-layout.md specification and implemented across the bin/omarchy-provision-user and configuration refresh utilities.

The Three-Stage Population Pipeline

Omarchy’s home directory construction follows a strict temporal separation between system-level skeletons and user-specific runtime state.

Stage 1: Seed via /etc/skel/

When a system administrator creates a new user with useradd -m, Arch Linux automatically copies the contents of /etc/skel/ into the newly created $HOME directory. In Omarchy, this directory is populated by the omarchy-settings package and contains the static, version-controlled defaults that every user requires at inception.

This is the only stage that executes automatically at user creation time. Files placed here include base configuration templates, directory structures, and static dotfiles that do not require runtime expansion or system-state detection.

Stage 2: Finalize via omarchy-provision-user

After the initial seed, the bin/omarchy-provision-user script performs runtime-dependent initialization that cannot be handled by /etc/skel/ alone. This stage executes once per user through the omarchy finalize user command.

According to the Omarchy source code, this script handles actions requiring:

  • $OMARCHY_PATH expansion for system-specific paths
  • Runtime detection of hardware or environment capabilities
  • Per-user plugin installation
  • System-state-dependent tweaks that rely on the live installation

The finalize stage bridges the gap between static skeleton files and a fully functional user environment tailored to the specific Omarchy installation.

Stage 3: Resync via omarchy-refresh-config

When existing users need to reset their configurations to the shipped defaults—effectively clobbering local modifications—they invoke omarchy reinstall-configs (implemented by the bin/omarchy-refresh-config utility). This destructive command overwrites user configuration files with canonical versions from the omarchy-settings package.

Unlike the Seed stage, which only affects new users, and the Finalize stage, which runs once per user, the Resync stage can be executed repeatedly to force a "factory reset" of configuration files while preserving user data.

Key Implementation Files

The population pipeline is documented and implemented across these authoritative source files:

  • docs/file-layout.md — Defines the three-stage conceptual model and the separation of concerns between /etc/skel/, provision scripts, and refresh utilities. (View source)
  • bin/omarchy-provision-user — The finalize-stage script that executes runtime-dependent configuration tasks requiring live system state. (View source)
  • bin/omarchy-refresh-config — The resync-stage utility that destructive overwrites user configs with package defaults. (View source)

Practical Usage Examples

The following commands demonstrate each stage of the population pipeline:


# Stage 1: Seed (automatic at user creation)

sudo useradd -m alice

# Copies /etc/skel/* to /home/alice

# Stage 2: Finalize (run once per user)

omarchy finalize user

# Executes bin/omarchy-provision-user for runtime-specific setup

# Stage 3: Resync (destructive refresh of specific configs)

omarchy reinstall-configs hypr/bindings.lua

# Overwrites ~/.config/hypr/bindings.lua with package default

Summary

  • Seed uses /etc/skel/ to deliver static defaults automatically when useradd -m creates a new account.
  • Finalize runs bin/omarchy-provision-user once per user to apply system-dependent configurations that require runtime detection.
  • Resync provides a destructive reset mechanism through bin/omarchy-refresh-config to clobber modified configs with package originals.
  • Only the Seed stage executes automatically; Finalize requires explicit invocation, and Resync is opt-in for configuration recovery.

Frequently Asked Questions

What is the difference between Seed and Finalize stages?

Seed copies static files from /etc/skel/ during user creation and cannot access runtime variables or system state. Finalize executes omarchy-provision-user after the user exists to perform dynamic configuration requiring $OMARCHY_PATH expansion, hardware detection, or per-user plugin installation that depends on the live system.

When should I run omarchy finalize user?

Run omarchy finalize user immediately after creating a new user or when migrating an existing user to a new Omarchy installation. According to the source code in bin/omarchy-provision-user, this command performs one-time initialization that links the user environment to the specific Omarchy installation path and capabilities.

Will omarchy reinstall-configs delete my personal data?

No. The Resync stage implemented by bin/omarchy-refresh-config only overwrites configuration files tracked by the omarchy-settings package (typically under ~/.config/). User documents, downloads, and personal files remain intact, though any customizations to Omarchy-managed config files will be lost.

Can I customize what gets copied to new users?

Yes. Modify the files in /etc/skel/ owned by the omarchy-settings package to change the default Seed template. However, these changes only affect users created after the modification; existing users retain their original seeded files unless they manually Resync or administrators run provisioning scripts manually.

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 →