CLI tool
nicknisi/dotfiles avatar
nicknisi/dotfiles

nicknisi/dotfiles: A Mise-Driven macOS Setup That Doubles as a Devcontainer Test

vim, zsh, git, homebrew, neovim - my whole world

2,992 stars372 forksShellMIT

At a glance

What is it?
This is a personal dotfiles repository built around Mise bootstrap, with a Linux devcontainer used to smoke-test the portable parts. It targets Apple Silicon Macs and assumes a specific checkout path and SSH setup.
Who is it for?
Adopt this if you are a single-user macOS developer who wants a reproducible environment and is willing to commit to Mise, a fixed checkout path, and a specific set of tools. Do not adopt it if you need a multi-machine portable setup or prefer to manage dotfiles with GNU Stow or chezmoi.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Shell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 14, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What This Repository Actually Is

Nick Nisi's dotfiles are not a starter kit. The README says so directly: "These are my actual dotfiles, not a starter kit." That distinction matters. The repository encodes one person's macOS setup, with an Apple Silicon assumption, a checkout at ~/Developer/dotfiles, and a set of personal repositories cloned over SSH. It is built around Mise, a version manager and task runner, which handles the bootstrap from a bare machine to a configured one. The intended user is a developer who uses Neovim, zsh, tmux, and a specific set of CLI tools, and who wants that environment reproduced on a new Mac or in a devcontainer. The devcontainer runs the same bootstrap in Ubuntu, which gives a way to test the portable terminal configuration without touching the host. That is a practical approach for a personal setup, but it also means the repository is opinionated in ways that a general-purpose dotfiles framework would not be.

The Mise Bootstrap Mechanism

The core of the setup is config/mise/config.toml, described as the machine manifest. A full mise bootstrap runs seven steps. On macOS, a pre-packages hook installs Homebrew, apps, and fonts. Then OS-specific packages are installed, either via Homebrew or apt in the Linux devcontainer. Repositories are cloned over SSH, dotfile symlinks are applied, macOS defaults are set, runtimes and tools are installed, and a bootstrap task registers a Git clean filter for pi-settings. The installer points Mise at the cloned config, so the same manifest handles both the first run and subsequent updates. The data flow is straightforward: install.sh clones the repo, installs Mise, and runs the bootstrap. The manifest declares everything, from packages to symlinks. This is a different model from a shell script that copies files. Mise tracks state, which means you can apply or unapply individual symlink targets with commands like mise bootstrap dotfiles apply --yes ~/.config/nvim. That granularity is useful when you want to change one editor config without touching the rest.

Getting It Running: Commands and Assumptions

The README gives a one-liner for a Mac: curl -fsSL https://raw.githubusercontent.com/nicknisi/dotfiles/main/install.sh | bash. That command checks for Git, clones the repository, installs Mise, and runs the full bootstrap. If the Xcode Command Line Tools are missing, the first run opens Apple's installer and stops; you run the command again after that finishes. There is also a dry-run flag: curl -fsSL ... | bash -s -- --dry-run, with NO_COLOR=1 for plain output. For a manual run, the steps are explicit: install Xcode tools, clone to ~/Developer/dotfiles, install Mise, set PATH to include ~/.local/bin and /opt/homebrew/bin, then run MISE_GLOBAL_CONFIG_FILE=~/Developer/dotfiles/config/mise/config.toml mise bootstrap --yes. The explicit config file path is only needed before bootstrap creates ~/.config/mise. After the install, you run mise run setup-git to set the local Git identity, which writes ~/.gitconfig-local. The bootstrap assumes Apple Silicon Homebrew paths under /opt/homebrew and a working GitHub SSH key for the additional repositories. If you do not have those, the install will fail or behave unexpectedly.

What Gets Installed and How It Is Organized

The repository layout is explicit. config/ holds app configuration that goes to ~/.config/*. home/ holds home-directory files like ~/.claude, ~/.pi, and ~/.zshenv. bin/ contains personal commands placed on PATH, and tools/ has larger one-off tools. The dotfiles symlink declarations in the manifest are broad: "~/.config/*" maps to the config directory, and "~/.??*" maps to home dotfiles. Mise links directories, not individual files, which means the entire config directory is symlinked. That is efficient but also fragile, because the source path is fixed. The README says the repository must live at ~/Developer/dotfiles unless you edit the manifest. The installed software list is long: Node.js 24, Python 3.14.7, pnpm, Bun, Deno, Lua, tree-sitter, plus tools like bat, delta, eza, fd, fzf, GitHub CLI, lazygit, ripgrep, Starship, tmux, zoxide, and Neovim. On macOS it also installs AeroSpace, Ghostty, WezTerm, Karabiner-Elements, SketchyBar, Borders, Monaspace, and Symbols Nerd Font. There are also personal repositories cloned over SSH: pi-extensions, ideation, and claude-plugins. If you do not have those repositories or do not want them, the bootstrap will fail or pull in unwanted code.

The Devcontainer as a Smoke Test

The .devcontainer/ directory runs the same bootstrap in Ubuntu. This is a notable design choice. Instead of maintaining a separate Linux setup, the author uses the devcontainer to test the portable terminal configuration. The README says the devcontainer runs the same bootstrap in Ubuntu so the author can edit and check the portable configuration without changing the host. That means the bootstrap must handle both macOS and Linux, which it does through OS-specific package lists and the pre-packages hook that only runs on macOS. The devcontainer is a smoke test, not a full environment. It will not have Homebrew, macOS defaults, or GUI apps. That is a limitation if you want a Linux desktop setup, but it is a reasonable way to catch portability issues in the zsh, Neovim, and CLI tool config. The README does not document how to build or run the devcontainer, but the presence of .devcontainer suggests it works with Docker or a tool like VS Code's Remote Containers. If you adopt this repository, the devcontainer is the first place to look when you change shell or editor behavior.

Symlink Management and Its Pitfalls

Mise manages symlinks as part of the bootstrap. You can check status with mise bootstrap dotfiles status, apply with --yes, and unapply with --yes. The README warns that Mise refuses to overwrite a real file with a symlink unless you pass --force. That is a safety measure, but it also means you need to know what is already in ~/.config before applying. If you have a real file at ~/.config/nvim, the apply will fail without --force, and using --force will replace it. The README also suggests commands to find dangling links: find ~/.config -type l ! -exec test -e {} \; -print. Those commands only print candidates, so you must check each target before removing it. This is a manual cleanup process. The broad symlink patterns mean that any file you add to the config/ directory will be linked, which can be surprising if you forget a file is there. The unapply command is useful, but the README explicitly says to unapply a target before deleting or renaming its source. If you delete the source without unapplying, you get a dangling symlink.

Maintenance, Upgrades, and License

The repository has a mise run update task that updates Neovim plugins, Homebrew, zsh plugins, Mise tools, uv tools, Pi extensions, and the repository itself. That is a single command for routine maintenance, which is convenient. However, the README does not document what the update task does in detail, nor does it mention any rollback mechanism. If an update breaks something, you are on your own. The repository is licensed under MIT, which means you can copy and modify it freely, but the README makes clear it is personal. The bootstrap clones personal repositories over SSH, so if you fork this repo, those clones will fail unless you have access to those repositories. The maintenance cost is tied to the author's workflow. If you adopt it, you will need to maintain your own fork and update the manifest to match your tools. The license allows that, but the fixed path and personal repos are barriers. The devcontainer provides a way to test changes before applying them to the host, which is a form of safety, but there is no mention of automated tests or CI for the bootstrap itself.

Alternatives and When This Is the Wrong Tool

A common alternative is GNU Stow, which manages dotfiles by creating symlinks from a single directory to your home directory. Stow is simpler: you keep your dotfiles in a directory, and stow creates symlinks for each file. The difference is that Stow does not handle package installation or system configuration. It only manages symlinks. Another alternative is chezmoi, which is a dotfile manager that can also run scripts and manage templates. chezmoi is more portable because it does not assume a fixed checkout path; it uses a source directory that you can place anywhere. The nicknisi/dotfiles approach is tied to Mise and a fixed path, which is a trade-off. If you want a tool that works across different machines with different directory layouts, chezmoi is more flexible. If you want a single command that installs everything from a bare Mac, this repository does that, but only for the author's specific setup. For a multi-user team or a beginner, this is the wrong tool because it is not a framework. It is a snapshot of one person's environment. The README's note about the old vim+tmux talk also shows that the setup changes substantially over time, so any fork will quickly diverge.

Editorial conclusion

Adopt this if you are a single-user macOS developer who wants a reproducible environment and is willing to commit to Mise, a fixed checkout path, and a specific set of tools. Do not adopt it if you need a multi-machine portable setup or prefer to manage dotfiles with GNU Stow or chezmoi. Before adopting, verify that your GitHub SSH key works, that you accept the /opt/homebrew assumption, and that the devcontainer's Ubuntu bootstrap matches your Linux needs. Check the config/mise/config.toml for the full list of packages and repos, and run the dry-run installer on a test machine first.

Official sources

  1. Official README
  2. Project repository
Community notes

Community notes