Dotfiles
nixos, nix-darwin, homebrew, oh-my-zsh, dotbot, dotbins, macos, linux, submodules, zsh, bash, awesome modern CLI tools — no place like ~/
Install / Use
/learn @basnijholt/DotfilesREADME
🏠 basnijholt's dotfiles
<img src="https://github.com/user-attachments/assets/8aeb6c8f-0cdc-4e04-a279-f70b3000ead7" align="right" style="width: 350px;" />A carefully designed cross-platform dotfiles configuration that powers my development environments across macOS and Linux 🐧 systems. This repository represents years of refinement to create a consistent, modular, and reliable setup.
I run this configuration on at least 10 machines, including arm64 macOS, x86_64 and aarch64 versions of Ubuntu, Debian, DietPi, Raspberry Pi OS, NixOS, Pop!_OS, and even on my iPhone via iSH which emulates i386 Linux.
My main goal is to have consistency and a super smooth bootstrapping experience for new machines, and to have a consistent setup across all my devices.
Try out my setup in Docker without installing anything! 🐳
See this section.
Want to install right away? Use the public branch for a sanitized version without private bits.
[!TIP] I have written several blog posts about my shell setup and the tools I use. See Open Sourcing My Dotfiles: A Practical, Cross-Platform Terminal Setup 🏠, Be a Ninja in the Terminal 🥷, dotbins: Managing Binary Tools in Your Dotfiles 🧰, and Combining Keychain and 1Password CLI for SSH Agent Management 🔑 for more details.
[!NOTE] I have maintained this repository since 2019-04 but started a new commit history when I made it public in 2025-04.
[!NOTE] Nearly all code snippets in this README are auto-generated by markdown-code-runner. Therefore, the code should be up-to-date.
✨ Features
- Shell agnostic - Works with both
zshandbash - Cross-platform - Supports macOS and Linux
- Modular design - Organized in independent, composable configuration files
- Easy installation - Uses dotbot for automated symlink management
- Binary management - Uses dotbins for CLI tools with automatic shell integration
- Remote syncing - Includes scripts to sync dotfiles across machines
- nix-darwin integration - Uses Nix for declarative macOS configuration
💖 My favorite things
There is a lot of stuff in this repository, but things I won't go without are:
- I clone this repository and run
./install, and everything is set up automatically! - oh-my-zsh for all of the convenient default keybindings and plugins (yes, I know it's bloated and slow)
- zsh-autosuggestions for command completion
- starship for a beautiful prompt
- dotbins for managing binaries
- dotbot for managing symlinks and installing Python tools with
uv - keychain for SSH key management
- direnv for managing environment variables (especially for Python (
uvandmicromamba)) - zoxide for jumping around directories (alternative to
zsh-z) - Keyboard Maestro for keyboard shortcuts to switch between applications
- zsh-syntax-highlighting for syntax highlighting
- nix-darwin for declarative macOS configuration
Why not?
- I don't use
fishbecause I want to be fully compatible withbash, so therefore I usezshas my main shell. - Why not X? I go over my design goals and decisions in this blog post.
🚀 Quick Start
Prerequisites
- Git and Git LFS installed (on macOS
brew install git git-lfsorapt install git git-lfson Debian/Ubuntu) - SSH key set up with GitHub (submodules use SSH)
# Initialize Git LFS (required once per machine, sets up global hooks)
git lfs install
# Ensure your key is loaded in the agent
ssh-add -l >/dev/null 2>&1 || ssh-add ~/.ssh/id_ed25519
Install the Public Branch
If you’re not me and just want a clean version without private bits, use the always-up-to-date public branch.
CI rebuilds it from main and removes anything listed in .publicignore, like the secrets submodule, personal machine configs, etc.
# Clone the sanitized branch with submodules (shallow)
git clone --depth=1 --branch public --single-branch \
--recurse-submodules -j8 --shallow-submodules \
git@github.com:basnijholt/dotfiles.git ~/dotfiles
cd ~/dotfiles
./install
One-line bootstrap (macOS & Linux)
A single command that installs prerequisites, clones the repo, initializes submodules, and runs ./install:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/basnijholt/dotfiles/public/scripts/bootstrap.sh)"
Works on macOS (Apple Silicon) and Linux (Alpine, Debian, Ubuntu, Fedora, Arch).
macOS Terminal Font
If prompt icons show as empty squares, install a Nerd Font and select it in Terminal.app:
brew install --cask font-fira-mono-nerd-font
brew install zsh git-lfs eza # General useful tools
Then in Terminal: Settings → Profiles → Text → Font → choose “FiraMono Nerd Font Mono”. The “Mono” variant forces single‑width glyphs so powerline/nerd icons align perfectly in Terminal.app.
Installation for me (@basnijholt)
First, you need to set up SSH authentication to access private submodules.
<details> <summary><b>Using 1Password</b></summary>Install 1Password and set up the SSH agent:
export SSH_AUTH_SOCK=~/Library/Group\ Containers/2BUA8C4S2C.com.1password/t/agent.sock
</details>
# Clone the repository with submodules
git lfs install
git clone --recurse-submodules -j8 git@github.com:basnijholt/dotfiles.git
cd dotfiles
# Run the installation script
./install
Trying with Docker
[!NOTE] Check out how minimal the
Dockerfilereally is, it only requires a barebones Ubuntu image and Git!
If you want to quickly try out this shell environment without installing it on your main system, you can use the provided Dockerfile:
# Build the Docker image
docker build -t dotfiles-env .
# Run the container and drop into the configured shell
docker run -it --rm dotfiles-env
This will give you an interactive Zsh session within an Ubuntu container, configured using these dotfiles.
Update Remote Machines
# Sync dotfiles to all configured remote hosts
./scripts/sync-dotfiles.sh
# Or install new configuration on remotes
./scripts/sync-dotfiles.sh install
🧩 Repository Structure
<!-- CODE:BASH:START --> <!-- python3 .github/scripts/repo_structure.py --> <!-- CODE:END --> <!-- OUTPUT:START --> <!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->.
├── Dockerfile # Docker container that runs this dotfiles configuration
├── LICENSE
├── README.md # You are here
├── configs # Configuration files for various tools
│ ├── agent-cli # Agent CLI configuration
│ ├── amp # Amp Code settings
│ ├── atuin # Shell history management
│ ├── bash # Bash-specific configuration
│ ├── bat # bat pager configuration
│ ├── claude # Claude Code settings
│ ├── codex # Codex CLI configuration
│ ├── conda # Conda/Mamba configuration
│ ├── dask # Dask distributed computing
│ ├── direnv # Directory-specific environment setup
│ ├── gemini # Gemini settings
│ ├── git # Git configuration
│ ├── hypr # Hyprland window manager config
│ ├── hyprpanel # Hyprpanel configuration
│ ├── iterm # iTerm2 profiles
│ ├── karabiner # Keyboard customization for macOS
│ ├── keyboard-maestro # Keyboard Maestro macros and configurations
│ ├── lazygit # lazygit configuration
│ ├── mako # Wayland notifications (mako)
│ ├── mamba # Mamba package manager settings
│ ├── nix-darwin # Nix configuration for macOS
│ ├── nixos # NixOS system configurations
│ ├── nvim
│ ├── opencode
│ ├── shell # Shell-agnostic configurations
│ ├── skhd
│ ├── starship # Cross-shell prompt
│ ├── syncthing # File synchronization
│ ├── wezterm # WezTerm terminal configuration
│ ├── yazi
│ ├── zellij # Zellij terminal multiplexer config
│ └── zsh # Zsh-specific configuration
├── install # Installation script
├── install.conf.yaml # Dotbot configuration
├── submodules # Git submodules for external tools
│ ├── autoenv # Directory-based environments
│ ├── dotbins # Binaries manager in dotfiles
│ ├── dotbot # Dotfiles installation
│ ├── mechabar # Waybar + Rofi theme (Hyprland)
│ ├── mydotbins # CLI tool binaries managed by dotbins
│ ├── oh-my-zsh # Zsh frame
