Modern dotfiles installer with animated progress display.
Clone and run the dotfiles installer from https://github.com/jiunbae/settings
Quick install: curl -LsSf https://settings.jiun.dev | bash -s -- --all
Core only: curl -LsSf https://settings.jiun.dev | bash -s -- --core
Pick & choose: curl -LsSf https://settings.jiun.dev | bash -s -- zsh nvim tmux tools
Post-install: exec zsh
# everything
curl -LsSf https://settings.jiun.dev | bash -s -- --all
# pick components
curl -LsSf https://settings.jiun.dev | bash -s -- zsh nvim tmux
# choose from a menu
curl -LsSf https://settings.jiun.dev | bash -s -- --interactiveOr clone it first:
git clone https://github.com/jiunbae/settings.git && cd settings
./install.sh --all| Preset | Installs |
|---|---|
--all |
everything |
--core |
base, zsh, nvim, tmux, tools |
--basic |
base, zsh, nvim, tmux |
| (no args) | interactive selector |
| Area | Components |
|---|---|
| Shell | zsh + zinit + Powerlevel10k, with autosuggestions and fast-syntax-highlighting · PowerShell 7 + starship + PSFzf on Windows |
| Editor | NeoVim + LazyVim, with the tree-sitter CLI for parsers |
| Multiplexer | tmux + TPM · zellij · rmux on Windows |
| CLI tools | eza ls · fd find · ripgrep grep · fzf |
| CLI extras | delta git diff · dust du · procs ps · bottom htop |
| Toolchains | Rust + cargo-binstall · uv · nvm on macOS, fnm on Windows |
| AI agents | Claude Code · Codex · cship statusline — see agent-state.md |
| History | hishtory — context, search, cross-device sync |
| macOS | Keyboard, shortcuts, Caps Lock → Control, Finder and menu bar preferences · Nerd Fonts · Hammerspoon · cmux · git config · nvm + Node LTS + Codex/Claude Code CLIs — see macos.md |
Components install independently and are safe to re-run; --dry-run previews any
combination of them without changing anything.
| Platform | Package manager | Architecture | Installer |
|---|---|---|---|
| Ubuntu/Debian | apt | x86_64, arm64 | install.sh |
| macOS | Homebrew | Intel, Apple Silicon | install.sh |
| WSL | apt | x86_64 | install.sh |
| Windows | winget | x86_64 | manual — windows.md |
Note
install.sh does not run on Windows: lib/platform.sh detect_platform exits on
anything that is not Linux or Darwin. Windows configs live in configs/ and are
placed by hand, following the same pattern as configs/windows-terminal/.
Usage: install.sh [OPTIONS] [COMPONENTS...]
Options:
-i, --interactive Interactive component selector (default when no args)
-a, --all Install all components
--core Install core dev environment (base, zsh, nvim, tmux, tools)
-b, --basic Install basic dev environment (base, zsh, nvim, tmux)
-f, --force Force reinstall (overwrite existing)
-c, --copy Copy config files instead of symlink
-l, --link Create symlinks for config files (default)
-v, --verbose Enable verbose output
-n, --dry-run Show what would be done without making changes
--no-sudo Skip commands that require sudo privileges
-h, --help Show this help message
--version Show version
Components:
base Basic packages (curl, wget, git, build-essential)
zsh Zsh + zinit + Powerlevel10k
nvim NeoVim + LazyVim
tmux tmux + TPM (terminal multiplexer)
zellij zellij (modern terminal multiplexer)
rust Rust toolchain + cargo-binstall
uv uv (fast Python package manager)
tools CLI tools (eza, fd, ripgrep, fzf)
tools-extra Extra CLI tools (delta, dust, procs, bottom)
ssh SSH config (copy only, not symlinked)
hishtory hishtory (better shell history with self-hosted sync)
macos macOS preferences (macOS-only: keyboard, shortcuts, Caps Lock->Control, Finder, menu bar)
fonts Nerd Fonts + JetBrainsMonoHangul (macOS-only)
hammerspoon Hammerspoon (macOS-only: window manager + keybindings)
ghostty Ghostty terminal config (macOS-only: Option-as-Alt so TUI Alt bindings work)
cmux cmux terminal (macOS-only: reads the Ghostty config)
git Git shared config, global ignore, commit signing (macOS-only)
node nvm + Node.js 24 LTS + Codex and Claude Code CLIs (macOS-only)
codex Codex CLI/App config, hooks, and notify chain
claude Claude Code settings, hooks, skill index, memory, MCP servers
cship cship + Starship (fast Claude Code statusline, replaces ccstatusline)
scripts Personal CLI scripts linked into ~/.local/bin
Opt-in components:
Excluded from --all and the interactive menu. Name them explicitly.
secrets SSH/GPG keys, env files and app data (aas, BarShelf, OTPeek) restored from the vault
secrets restores private material from a Bitwarden-compatible vault. The list of
what to restore is a manifest kept inside the vault, so this public repository
carries the restore engine and none of the inventory — see docs/secrets.md.
On Windows, where install.sh does not run, bin/windows/Restore-Secrets.ps1 restores
from the same vault — see windows.md.
./install.sh secrets # this vault
SETTINGS_VAULT_SERVER=https://vault.example.com \
./install.sh secrets # someone else's./install.sh --dry-run --all # preview, change nothing
./install.sh -v zsh # one component, verbose
./install.sh --force zsh # reinstall over an existing setup
cat ~/.install.log # what actually happenedexec zsh # or: source ~/.zshrc
eza --version && rg --version # sanity checkThe aliases come from home/dot_zshrc: ls/ll/la/lt → eza, find → fd,
grep → rg, du → dust, ps → procs, top/htop → btm, vim/vi → nvim, and
zs/za/zl for zellij sessions. The ta/tl/ts/to/tds session shortcuts run
rmux where it is installed and tmux otherwise, and are left undefined when neither is.
The PowerShell profile mirrors these, except that
the ones shadowing an existing command stay interactive-only — see
windows.md.
settings/
├── install.sh # Main installer
├── bootstrap.sh # One-line installer (also published to gh-pages)
├── lib/ # Shared: cli, core, platform
├── modules/ # One file per component
├── .chezmoiroot # "home": chezmoi reads its source from home/ only
├── home/ # The dotfiles, named the way chezmoi places them
│ ├── dot_zshrc dot_p10k.zsh dot_tmux.conf
│ ├── dot_config/ # nvim/ zellij/ git/ starship.toml cship.toml
│ ├── dot_local/bin/ # personal CLI scripts, placed on PATH
│ ├── private_dot_ssh/ # ssh config, mode 600
│ └── Library/ # Ghostty, key bindings (macOS)
├── configs/ # What is not placed as-is: merges, seeds, Windows
│ └── claude/ codex/ cmux/ hishtory/ git/ macos/ powershell/ windows-terminal/
├── bin/windows/ # Windows-only; install.sh never sees this dir
├── scripts/ # Build and maintenance helpers
├── docs/ # The guides linked below, plus the README GIF
│ └── demo.tape # and the VHS tape and sandbox that record it
├── .gitea/workflows/ # Releases run on the self-hosted Gitea runner
└── worker/ # Cloudflare Worker — written, never deployed
| chezmoi.md | The move to chezmoi: where it stands, how to edit, what must never happen |
| macos.md | Keyboard, shortcuts, Finder, fonts, cmux and git on macOS |
| components.md | hishtory sync, Hammerspoon permissions, the managed Codex config |
| windows.md | rmux, PowerShell, NeoVim, Windows Terminal, Nextcloud upload, secrets restore |
| powershell.md | How the PowerShell profile went from 1354ms to 394ms |
| agent-state.md | Restoring Claude Code / Codex state on a new machine |
| tmux-to-zellij.md | Migration notes |
settings.jiun.dev is GitHub Pages from the gh-pages branch, not the Worker in
worker/ — that was written but never deployed. gh-pages carries its own copy of
bootstrap.sh, duplicated as index.html so the pathless one-liner works, and nothing
syncs it automatically.
Important
After changing bootstrap.sh, run scripts/sync-gh-pages.sh --push. The copy once
went stale for five months — long enough that the published installer was missing the
guard that refuses to git reset --hard over uncommitted local changes.
The GIF at the top is recorded with VHS and checked in, so it goes stale the same way. After changing the progress display, the component list or the summary, re-record it:
vhs docs/demo.tape # ~35s, rewrites docs/demo.gifIt installs nothing and never touches $HOME: the tape's prelude points the installer
at a scratch HOME and a directory of shims, and its postlude removes them. The
installer itself is real and has no demo mode — see
demo-README.md, including the note about pinning VHS to v0.11.0,
because v0.12.0 exits 0 without writing the file.
MIT
