- Shell 42.9%
- Lua 29.6%
- JavaScript 16.2%
- Ruby 9.6%
- Swift 1.7%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| docs | ||
| installs | ||
| profiles | ||
| scripts | ||
| AGENTS.md | ||
| CLAUDE.md | ||
| log.txt | ||
| README.md | ||
| setup.sh | ||
dotfiles
Personal development-environment installer. It layers one or more profiles onto $HOME by symlinking files from profiles/<profile>/home, then syncs platform packages for the selected profiles.
Usage
./setup.sh --dry-run base personal
./setup.sh --force base personal
./setup.sh # Reapply saved profiles.
Options:
--dry-run: print the links and package installs that would happen.--force: move conflicting real files/directories into~/.dotfiles-backup/<timestamp>/before linking.--no-packages: link files only, skipping every package manager. For environments whose packages are already baked in — the Coder workspace image inenvs/coderapplies profiles on every start and would otherwise re-runpacman -Syu, which is slow and stops on an interactive prompt when an upgrade is pending.
Profiles are applied in order. Later profiles win when they replace an earlier profile's symlink.
Each successful non-dry run with explicit profiles adds them—once and in first
application order—to $XDG_CONFIG_HOME/dotfiles/profiles (default:
~/.config/dotfiles/profiles). With no profiles, setup applies that saved list.
Edit the file to remove a profile that should no longer be selected.
Profiles
base: shared shell, editor, Git, terminal, and development-tool configuration.termux: Android/Termux packages and the Atuin encryption-key setup workaround.personal: personal Git identity, SSH host snippets, and Homebrew bundle.work: work Git identity, SSH host snippets, project-local Git config, and Homebrew bundle.bitwarden: Bitwarden-specific shell and SSH snippets.linux-desktop: the graphical session layer shared by every Arch machine with a display — terminal, audio, Bluetooth, networking, clipboard, screenshots, fonts, Flatpak, and Steam.xps-13-7390: Dell XPS 13 7390 firmware, Thunderbolt, power-profile, Intel media, and Vulkan support.arch-desktop: Ryzen 5 3600 microcode, AMD platform/GPU firmware, Radeon RX 9070 XT Vulkan and ROCm support, plus SSD health tooling.
On Android/Termux, explicitly select the platform profile:
./setup.sh --dry-run base personal termux
./setup.sh base personal termux
Termux packages live in profiles/termux/packages/termux.txt, not base.
The profile's setup hook runs after package installation and securely creates a
missing Atuin encryption key without hard links (denied by Android). Existing
keys are never replaced, and custom Atuin key paths are respected. The hook is
Android-only, is previewed without execution by --dry-run, and also runs with
--no-packages when Atuin is already installed.
Apply the XPS profile last on that laptop:
./setup.sh --force base personal bitwarden linux-desktop xps-13-7390
The profile does not force a thermal profile or charging threshold. Those remain
the firmware-managed user choices exposed by powerprofilesctl and the kernel.
Apply the desktop profile last on the Arch workstation:
./setup.sh --force base personal bitwarden linux-desktop arch-desktop
Then enable periodic trimming and SMART monitoring:
sudo ./installs/configure-storage-maintenance.sh
Configure a graphical encrypted-root prompt after the machine boots successfully through systemd-boot:
sudo ./installs/configure-plymouth.sh
The installer temporarily preserves the current initramfs as a separate pre-Plymouth systemd-boot recovery entry. After a successful Plymouth boot, remove the temporary entry and image before the next kernel upgrade:
sudo rm /boot/loader/entries/arch-pre-plymouth.conf \
/boot/initramfs-linux-pre-plymouth.img
How linking works
setup.sh recursively scans profiles/<profile>/home and symlinks every file into the matching path under $HOME.
If a directory contains a .link marker, the whole directory is symlinked instead of scanning its contents. This is useful for config directories that should be owned as one unit, such as ~/.config/nvim.
Package manifests
- Homebrew: profiles that include
home/Brewfileexpose it as~/Brewfile; setup runsbrew bundleagainst the last selected profile'sBrewfilewhen Homebrew is available. - Termux: profiles may include
packages/termux.txt; setup installs those packages withpkg install -ywhen running on Android/Termux. - Arch: profiles may include
packages/arch.txt; setup runssudo pacman -Syu --neededfor the selected manifests.packages/flatpak-remotes.txtdeclaratively adds system Flatpak remotes after Flatpak is installed. - Language runtimes: the base profile links
~/.config/mise/config.toml; its pinned portable-tool baseline is shared across platforms.
Arch terminal and workstation packages
Packages are split across three layers, by what each needs to exist:
baseinstalls the shell and terminal toolchain—Starship, Atuin, direnv, zoxide, Eza, Bat, Yazi, Lazygit, Jujutsu, Delta, Git LFS, Television. It is headless: it must stay installable with no display server, because Termux, macOS, and the Coder workspace container inenvs/coderall apply it. That container builds its Arch image from this exact manifest, so nothing needing a display server or themultilibrepo may be added here.linux-desktopinstalls the graphical session shared by every Arch machine with a display—Ghostty, PipeWire, NetworkManager, BlueZ, clipboard and screenshot tools, fonts, Flatpak, and Steam.- Hardware profiles (
arch-desktop,xps-13-7390) supply machine-specific firmware and graphics drivers.
The independent Orbit repository owns the Arch/Hyprland graphical session, including Hyprland, Waybar, Wofi, Mako, lock/idle, clipboard, portal, desktop-integration packages, and Flathub setup. Apply dotfiles and Orbit separately; neither repository invokes the other.
Runtime ownership
Platform package managers own OS bootstrap software and native integrations, including mise itself. Mise owns portable runtime versions; project mise.toml files override the global baseline. uv owns Python interpreters and environments once mise has installed its pinned uv executable. When a mise backend cannot support a platform such as Termux, the platform package manager may own that runtime as a documented exception. A native package's required runtime remains its package manager's transitive dependency—for example, Homebrew's mpv and yt-dlp require Deno on macOS—while mise selects the interactive Deno version.
Adding a profile
profiles// ├── home/ # optional files to symlink into $HOME ├── packages/arch.txt # optional Arch package manifest ├── packages/flatpak-remotes.txt # optional system Flatpak remotes └── packages/termux.txt # optional Termux package manifest
Profiles may also include setup.sh for idempotent configuration fixes. Setup
runs these hooks in profile order after package sync, with HOME set to the
target home directory. Hooks must guard platform-specific operations; dry runs
print the hook command without executing it. Do not put package installs in hooks.
Prefer adding profile-specific files over branching inside setup.sh. Use ./setup.sh --dry-run ... before applying a new profile to a real home directory.