# What Is the Finalize Step in Omarchy User Setup?

> Understand the Finalize step in Omarchy user setup. Learn how omarchy-provision-user creates symlinks, configures apps, and runs scripts for a personalized environment.

- Repository: [Omacom/omarchy](https://github.com/omacom/omarchy)
- Tags: getting-started
- Published: 2026-09-02

---

**The Finalize step is a per-user completion phase invoked by `omarchy-provision-user` that bridges the gap between system-wide defaults and a functional personal environment by creating symlinks, configuring default applications, and running user-level installation scripts.**

In the [omacom/omarchy](https://github.com/omacom/omarchy) repository, the Finalize step ensures that every newly created user receives the correct runtime configuration after the initial system skeleton is copied. Because many user-specific resources require an existing `$HOME` directory—which is not available when files are copied from `/etc/skel`—Omarchy provides a dedicated finalization script to handle these post-creation tasks.

## Why Omarchy Needs a Separate Finalization Phase

System-wide configuration files placed in `/etc/skel` can only contain static templates. They cannot create dynamic symlinks that point to repository locations, update user-specific PATH variables, or mark migration states because the target user’s home directory does not exist during the initial copy phase. The **Finalize** step solves this by running `omarchy-provision-user` after the home directory is established, ensuring the environment is fully operational before the user logs in.

## How the Finalize Step Works

The implementation lives in **`bin/omarchy-provision-user`**, a Bash script that orchestrates the remaining runtime tweaks. The script follows an idempotent design to prevent duplicate operations across multiple invocations.

### Idempotency and State Management

Before executing any changes, the script checks for a marker file at `~/.local/state/omarchy/done/finalize-user`. If this file exists, the script exits immediately unless the `--force` flag is provided. Upon successful completion, it writes the marker using the `omarchy-done mark finalize-user` helper function found in the `bin/` directory.

## Key Operations Performed During Finalization

### Environment Setup

The script guarantees that `OMARCHY_PATH`, `OMARCHY_INSTALL`, and updated `PATH` variables are available. This ensures that all subsequent helper functions can locate repository resources and external binaries.

### Dev-Aware Skill Symlinks

To support AI-assisted development workflows, the Finalize step creates symlinks under `~/.agents/skills`, `~/.claude/skills`, and similar directories. These point to the repository’s default skill folders, allowing users to run development-ready agents without copying static files into `/etc/skel`.

### XDG User Directories and GTK Bookmarks

The script creates standard user directories (`Downloads`, `Pictures`, `Videos`, etc.), updates `xdg-user-dirs` configurations, removes stale empty folders, and writes bookmarks for the GTK file chooser. This ensures the file manager presents a clean, organized structure consistent with Omarchy’s conventions.

### User-Level Installation Scripts

The central installation logic resides in [`install/user/all.sh`](https://github.com/omacom/omarchy/blob/main/install/user/all.sh), which the Finalize step sources during execution. This script pulls in additional per-user packages, configurations, or database migrations that cannot be applied system-wide.

### Application Refresh and Defaults

The script calls `omarchy-refresh-applications` to update the desktop environment’s application database. It then sets the default web browser to `chromium.desktop` and registers the default mail handler as `HEY.desktop`.

### First-Install Migration Marking

When invoked with the `--first-install` flag (typically during ISO installation), the Finalize step marks all shipped migrations as completed. This prevents the system from attempting to apply these migrations again during future updates.

## Running the Finalize Command

Users and administrators can trigger the Finalize step using the `omarchy` CLI:

```bash

# Run finalization for the current user (default, safe, idempotent)

omarchy finalize user

# Force a re-run after changing default applications or skills

omarchy finalize user --force

# Used by the installer ISO for brand-new user accounts

omarchy finalize user --first-install

```

## Core Files and Architecture

The Finalize step relies on the following components from the Omarchy codebase:

- **`bin/omarchy-provision-user`**: The main orchestration script that implements the Finalize step.
- **[`install/user/all.sh`](https://github.com/omacom/omarchy/blob/main/install/user/all.sh)**: Contains the bulk of per-user installation logic sourced during finalization.
- **`bin/omarchy-done`**: Provides the `check` and `mark` functions used for idempotency tracking.
- **[`docs/file-layout.md`](https://github.com/omacom/omarchy/blob/main/docs/file-layout.md)**: Documents the Finalize command as a top-level user-setup operation.

## Summary

- **The Finalize step** runs after `/etc/skel` copying to complete per-user setup in the actual `$HOME` directory.
- **Idempotency** is enforced via a marker file at `~/.local/state/omarchy/done/finalize-user` unless `--force` is used.
- **Key actions** include creating dev skill symlinks, configuring XDG directories, sourcing [`install/user/all.sh`](https://github.com/omacom/omarchy/blob/main/install/user/all.sh), and setting default applications like Chromium and HEY.
- **Execution** is handled by `bin/omarchy-provision-user` and invoked via `omarchy finalize user`.

## Frequently Asked Questions

### What happens if I run the Finalize step multiple times?

The script checks for the existence of `~/.local/state/omarchy/done/finalize-user` and exits immediately if found. This prevents duplicate symlinks, redundant directory creation, and re-running user-install scripts. To override this behavior, use the `--force` flag.

### Where does the Finalize step store its completion marker?

The idempotency marker is written to `~/.local/state/omarchy/done/finalize-user` using the `omarchy-done mark finalize-user` helper. This path ensures the state persists across sessions while remaining outside version-controlled config files.

### How do I force a re-run of the Finalize step?

Execute `omarchy finalize user --force` to bypass the marker file check. This is useful after updating default applications in the repository or modifying skill configurations that need new symlinks created.

### What is the difference between Finalize and the system-wide skeleton installation?

The system-wide skeleton (`/etc/skel`) provides static files copied at account creation time, but it cannot reference the user’s actual `$HOME` path or create dynamic symlinks. The **Finalize** step runs afterward with full access to the user environment to complete runtime-specific configuration.