Skip to content

Personal Machine

A complete example of a personal machine kit. Based on the dotkit-run/example repo.

  • Directorydotkit/
    • .dotkit
    • dotkit.env
    • Directoryconfigs/
      • dock.sh
    • Directorytools/
      • community.txt
    • Directorypackages/
      • brew.md
      • mas.txt
    • Directorygit/
      • git.env
      • config.txt
      • repos.txt
    • Directorypostconfigs/
      • dock.sh
    • Directorydotfiles/
      • .zshrc
      • .gitignore_global
    • Directorytodo/
      • setup.md

The entry point. It names every folder and the order they run in:

map dotkit run {{item}}
configs
tools
packages
git
postconfigs
---
dotkit link dotfiles
dotkit todo -f --title 'Setup Checklist' --out ~/TODO.md todo

Nothing else marks a folder. dotfiles/ is a symlink source because this file says so, and todo/ is a checklist for the same reason.

A bare .dotkit is named after its directory and runs without prompting.

Run it with:

Terminal window
dotkit run ~/dotkit

Variables available to everything in the kit:

Terminal window
DOTKIT_DEV_DIR="~/dev"

Shell scripts run first, before any tools are installed. No package manager required.

configs/dock.sh
defaults write com.apple.dock autohide -bool true
defaults write com.apple.dock tilesize -int 48
killall Dock

Install package managers and toolchains. Uses community modules:

tools/community.txt
map dotkit run :tools/{{item}}
brew
node-fnm
rust
uv

With tools in place, install everything else.

brew.md - Homebrew taps, formulae, and casks:

# Homebrew
## map
- brew tap **1**
- hashicorp/tap
## map
- brew install **1**
- gh
- ripgrep
- dockutil
## map
- brew install --cask **1**
- firefox
- visual-studio-code
- ghostty

mas.txt - Mac App Store apps (macOS only):

try command -v mas
brew install mas
echo 'Sign in to the App Store manually first'
---
map mas install {{key}}
# Development
497799835 = Xcode
# Communication
310633997 = WhatsApp

Git global config and repo clones. git.env provides a folder-scoped variable, read only for files in this folder:

git/git.env
MY_DEV_DIR=$DOTKIT_DEV_DIR

Any *.env name works. For a variable used by one file only, skip the file and set it in a block instead.

config.txt - set global git options:

git config --global core.excludesfile ~/.gitignore_global
---
map git config --global {{key}} {{value}}
#user.name = Your Name
#user.email = [email protected]
#init.defaultBranch = main

repos.txt - clone your repos:

map git clone [email protected]:{{1}}/{{2}}.git $MY_DEV_DIR/{{3}}
#yourname = dotkit = dotkit
#yourname = dotfiles = dotfiles

dotkit link dotfiles symlinks every file here to the matching path under ~:

dotfiles/.zshrc → ~/.zshrc
dotfiles/.gitignore_global → ~/.gitignore_global

The destination defaults to ~. Pass a second argument for anywhere else.

dotkit todo generates a checklist of steps that can’t be automated. Title and output path are arguments in the dotkit file, so the folder needs no configuration of its own.

todo/setup.md
- [ ] Sign in to the App Store
- [ ] Configure VPN
- [ ] Set up Password Manager

Re-apply symlinks after adding a dotfile:

Terminal window
dotkit link dotfiles

Preview a run without changing anything:

Terminal window
dotkit run --dry-run ~/dotkit

Install a new package and track it:

Terminal window
dotkit add packages/brew neovim

This adds neovim to the map block in brew.md and installs it immediately. It finds the kit by walking up from your working directory, so run it from inside the repo.