Skip to content

Your first dotfiles repository

This tutorial takes you from nothing to a working setup: a dotfiles repository with one configuration file and one setup script, deployed on your machine by configfile. It takes about ten minutes.

You need configfile installed and a GitHub account (any git hosting works the same way).

configfile doesn’t store your files: they live in a git repository that you own, usually called dotfiles.

Create an empty repository named dotfiles on GitHub, then clone it. This clone is your working copy: it’s where you edit your dotfiles.

Terminal window
git clone git@github.com:me/dotfiles.git ~/dotfiles
cd ~/dotfiles

A module is a folder of files/ that groups the configuration of one tool. Create one for zsh, with the file you want on every machine:

Terminal window
mkdir -p files/zsh
echo 'alias ll="ls -la"' > files/zsh/zshrc

Then tell configfile where this file goes, in the module’s settings.json:

files/zsh/settings.json
{
"files": [
{ "source_path": "zshrc", "target_path": "~/.zshrc", "deploy": "global" }
]
}

"deploy": "global" means the file is linked into your home folder. The modules reference lists every option.

Scripts go in scripts/. They’re handy for what files alone can’t do, such as installing tools:

scripts/setup.sh
#!/bin/sh
echo "Setting up $CONFIGFILE_OS from $CONFIGFILE_REPO"

CONFIGFILE_OS and CONFIGFILE_REPO are set by configfile when it runs the script (see Scripts).

Commit and push:

Terminal window
git add .
git commit -m "First module"
git push

Your repository now looks like this:

files/
zsh/
settings.json
zshrc
scripts/
setup.sh
Terminal window
configfile init --repo git@github.com:me/dotfiles.git
Info Cloning git@github.com:me/dotfiles.git into ~/.configfile/dotfiles…
Cloning into '/Users/me/.configfile/dotfiles'...
done.
Done configfile is ready. Configuration saved to ~/.configfilerc.

configfile keeps its own copy of the repository in ~/.configfile/dotfiles, and deploys from it. You never edit this copy: you edit your working copy, push, and configfile follows. How it works explains why.

Check where things stand:

Terminal window
configfile modules status
zsh:
~/.zshrc (not deployed: a file is in the way)

You probably already have a ~/.zshrc. Preview what deploying would do, without changing anything:

Terminal window
configfile modules deploy zsh --dry-run
Info Dry run, nothing is changed. Deploying zsh would do:
- ~/.zshrc (would be linked, the existing file moved to ~/.zshrc.old)
Done Dry run finished.

Your current file is kept, as ~/.zshrc.old. Deploy:

Terminal window
configfile modules deploy zsh
Info Deploying zsh…
- ~/.zshrc (deployed, previous file moved to ~/.zshrc.old)
Done Deployment finished.

~/.zshrc is now a link to the file in the repository:

Terminal window
ls -l ~/.zshrc
# ~/.zshrc -> ~/.configfile/dotfiles/files/zsh/zshrc
Terminal window
configfile scripts run setup
Info Running "setup"…
Setting up macos from ~/.configfile/dotfiles
Done Script "setup" finished.

Edit the file in your working copy, then push, as for any git repository:

Terminal window
cd ~/dotfiles
echo 'alias gs="git status"' >> files/zsh/zshrc
git commit -am "Add gs alias"
git push

Then bring the change to this machine:

Terminal window
configfile update
Info Syncing ~/.configfile/dotfiles…
Done Synced with origin/main (117f764). Global files are links, so they are up to date; run "configfile modules deploy --all" for new files.

Because ~/.zshrc is a link, the new alias is there right away. On your other machines, configfile update does the same.

configfile records every change it makes. In configfile history, the deployment and the sync look like this:

Terminal window
configfile history
2026-10-08 11:29 modules deploy zsh ok
linked ~/.zshrc (previous file moved to ~/.zshrc.old)
2026-10-08 11:29 update ok
synced ~/.configfile/dotfiles with origin/main (f9a3f1e → 117f764)

And every deployment can be reverted. undeploy removes the link and puts your previous file back:

Terminal window
configfile modules undeploy zsh
Info Undeploying zsh…
- ~/.zshrc (removed, ~/.zshrc.old restored)
Done Undeployment finished.
  • Modules and settings.json: local files copied into a project, files kept in the repository without being deployed, and every rule for targets.
  • Scripts: scripts in any language, folder scripts, and versions per system (setup.macos.sh).
  • Run scripts when a module is deployed: install plugins or start a service each time a module is deployed, and clean up when it is undeployed.
  • Commands: every command and option, including the ones for running configfile from scripts and CI.