Skip to content

Architecture

System architecture diagrams for understanding how the dotfiles repository is structured and operates.


Tool Dependency Graph

How the core tools relate to each other and what depends on what.

graph TD
    subgraph "Package Managers"
        mise["mise<br/>(tool manager)"]
        chezmoi["chezmoi<br/>(dotfile manager)"]
        antidote["antidote<br/>(zsh plugins)"]
        tpm["tpm<br/>(tmux plugins)"]
    end

    subgraph "Core Tools"
        zsh["zsh<br/>(shell)"]
        neovim["neovim<br/>(editor)"]
        tmux["tmux<br/>(multiplexer)"]
        git["git<br/>(version control)"]
    end

    subgraph "Security"
        age["age<br/>(encryption)"]
        gitleaks["gitleaks<br/>(secret scanning)"]
        precommit["pre-commit<br/>(git hooks)"]
    end

    subgraph "CLI Utilities"
        bat & eza & fd & ripgrep & fzf & zoxide & jq & delta
    end

    mise --> chezmoi
    mise --> age
    mise --> neovim
    mise --> bat & eza & fd & ripgrep & fzf & zoxide & jq & delta
    mise --> gitleaks
    mise --> precommit

    chezmoi --> age
    chezmoi --> git

    zsh --> antidote
    zsh --> fzf
    zsh --> zoxide
    zsh --> mise

    tmux --> tpm
    tmux --> git

    precommit --> gitleaks
    precommit --> git

    git --> delta

Data Flow

How dotfiles flow from the repository to your home directory.

flowchart LR
    subgraph repo["Git Repository"]
        direction TB
        dot_files["dot_* files<br/>(templates)"]
        encrypted["encrypted_*<br/>(.age files)"]
        chezmoi_data[".chezmoidata.yaml<br/>(per-distro packages)"]
        chezmoi_tmpl[".chezmoi.toml.tmpl<br/>(config template)"]
    end

    subgraph chezmoi_layer["Chezmoi Processing"]
        direction TB
        template_engine["Template Engine"]
        os_detect["OS Detection<br/>(Arch/Debian/macOS)"]
        decrypt["Age Decryption"]
    end

    subgraph home["Home Directory"]
        direction TB
        zshrc["~/.zshrc"]
        gitconfig["~/.gitconfig"]
        config_dir["~/.config/*"]
        secrets["~/.secrets"]
    end

    dot_files --> template_engine
    encrypted --> decrypt
    chezmoi_data --> os_detect
    chezmoi_tmpl --> template_engine

    os_detect --> template_engine
    decrypt --> secrets

    template_engine --> zshrc
    template_engine --> gitconfig
    template_engine --> config_dir

Deployment Modes

Three deployment modes for different environments.

graph TB
    subgraph full["Full Mode (Workstations)"]
        direction TB
        full_desc["scripts/bootstrap → mise run install → chezmoi apply"]
        full_tools["All tools from mise.toml<br/>Desktop apps, TUI tools, dev utilities"]
        full_config["Full dotfile templates<br/>Zsh, Neovim, Tmux, Git"]
        full_packages["System packages<br/>run_once_* scripts"]
    end

    subgraph server["Server Mode"]
        direction TB
        server_desc["mise-server.toml → chezmoi apply"]
        server_tools["Server-safe tools only<br/>No yazi, lazygit, lazydocker, atuin"]
        server_config["Full dotfile templates<br/>Zsh, Neovim, Tmux, Git"]
        server_skip["Skips: lolcat, tinty, pnpm, bun<br/>glow, onefetch, lnav"]
    end

    subgraph minimal["Minimal Mode (Dotfiles Only)"]
        direction TB
        minimal_desc["chezmoi init --apply --exclude run_once_*"]
        minimal_tools["No tool installation<br/>Uses system-provided tools"]
        minimal_config["Dotfile templates only<br/>Zsh, Git configs"]
        minimal_skip["Skips: all run_once scripts<br/>No package installation"]
    end

    user{{"Choose Deployment Mode"}}
    user --> full
    user --> server
    user --> minimal

    style full fill:#2d5a2d,color:#fff
    style server fill:#5a5a2d,color:#fff
    style minimal fill:#5a2d2d,color:#fff

Bootstrap Sequence

Step-by-step flow of the bootstrap process on a fresh machine.

sequenceDiagram
    participant User
    participant Bootstrap as scripts/bootstrap
    participant Mise as mise
    participant Chezmoi as chezmoi
    participant Home as Home Directory

    User->>Bootstrap: curl ... | bash
    Bootstrap->>Bootstrap: Display banner & confirm

    Note over Bootstrap: Step 1 - Install mise
    Bootstrap->>Mise: curl https://mise.run | sh
    Mise-->>Bootstrap: mise installed to ~/.local/bin

    Note over Bootstrap: Step 2 - Clone repo
    Bootstrap->>Bootstrap: git clone → ~/repos/dotfiles

    Note over Bootstrap: Step 3 - Prepare config
    Bootstrap->>Mise: mise trust

    Note over Bootstrap: Step 4 - Run install task
    Bootstrap->>Mise: mise run install
    Mise->>Mise: Install tools from mise.toml
    Mise->>Chezmoi: chezmoi init --apply
    Chezmoi->>Chezmoi: Detect OS (Arch/Debian/macOS)
    Chezmoi->>Chezmoi: Render templates
    Chezmoi->>Home: Write ~/.zshrc, ~/.gitconfig, etc.

    Note over Mise: Optional interactive prompts
    Mise->>Mise: Setup SSH keys?
    Mise->>Mise: Setup age encryption?

    Mise->>Mise: Install TPM & Antidote
    Mise->>Mise: Link mise config
    Mise->>Mise: Optional login-shell change prompt
    Mise->>Mise: Run doctor at end (interactive mode)
    Mise-->>User: Install + health check results

CI Pipeline

GitHub Actions workflow structure and job dependencies.

flowchart TB
    subgraph triggers["Triggers"]
        push["Push to main"]
        pr["Pull Request"]
        manual["Manual Dispatch"]
    end

    subgraph ci["ci.yml"]
        lint["lint<br/>ShellCheck on mise-tasks<br/>~7s"]
        docs_validate["docs-validate<br/>Markdown link check<br/>~50s"]
        docs_build["docs-build<br/>MkDocs build + lychee<br/>~25s"]
        build["build<br/>Install + Fast Tests + Doctor<br/>~45s"]
        server["test-server-deployment<br/>Chezmoi apply validation<br/>~30s"]
        windows["test-windows<br/>Pester + PowerShell<br/>~1m"]
    end

    push & pr & manual --> lint & docs_validate & docs_build & server & windows
    lint --> build

    subgraph build_steps["Build Job Steps"]
        direction TB
        b1["Install Mise"] --> b2["Cache Tools"]
        b2 --> b3["mise trust && mise install"]
        b3 --> b4["mise run install (x2 idempotency)"]
        b4 --> b5["mise run lint"]
        b5 --> b6["Fast Test Suite<br/>(static, smoke, basic, env, doctor)"]
        b6 --> b7["mise run doctor"]
        b7 --> b8["Server Mode Doctor"]
    end

    build -.-> build_steps

    style lint fill:#4a9eff,color:#fff
    style build fill:#4a9eff,color:#fff
    style docs_validate fill:#7b68ee,color:#fff
    style docs_build fill:#7b68ee,color:#fff
    style server fill:#2ecc71,color:#fff
    style windows fill:#e67e22,color:#fff


Implementation Details

Chezmoi Template System

All dotfiles are managed by chezmoi and live in the repository root with dot_ prefixes.

Key Template Variables: - .chezmoi.os: Operating system (linux/darwin) - .chezmoi.osRelease.id: Distro ID (arch/ubuntu/debian) - .packages.common: Package lists from .chezmoidata.yaml

Run-once Scripts: - run_once_before_*.sh.tmpl: Execute during chezmoi apply - Uses script hash to determine if re-run is needed (idempotent)

Mise Tasks

Automation is handled via mise tasks in mise-tasks/:

Directory Purpose
install Main setup (packages, dotfiles)
doctor Health checks
test BATS test suite
lint ShellCheck, yamllint

Tasks are bash scripts with metadata pragmas:

#MISE description="Check environment health"

Critical Architecture Rules

  1. Idempotency: All scripts must be safe to re-run multiple times.
  2. Package Boundaries: distro packages in .chezmoidata.yaml, cli tools in mise.toml.
  3. No Apt/Pacman Direct: Always use the abstraction layers.

Profiles Architecture

Comparison of components installed in different deployment modes.

graph TD
    subgraph "Base (All Profiles)"
        Dotfiles[Dotfiles Config]
        Chezmoi[Chezmoi]
        Mise[Mise Core]
    end
    subgraph "Server Profile"
        Base --> ServerTools
        ServerTools[Ripgrep, Fd, Bat, Eza]
        ServerTools --> NoGUI[No GUI Tools]
    end
    subgraph "Workstation (Default)"
        ServerProfile --> DesktopTools
        DesktopTools[Yazi, Lazygit, Atuin, Starship]
        DesktopTools --> Langs[Node, Python, Go, Rust]
    end