"Me fail dotfiles? That's unpossible."
A dotfiles manager written in Go. Declare your setup in a TOML file -- symlinks, copies, aliases, functions, repos, build hooks, packages -- and ralph up makes it happen. Idempotent, repeatable, no surprises.
# With Go 1.25+
go install github.com/mad01/ralph/cmd/ralph@latest
# Or build from source
git clone https://github.com/mad01/ralph.git
cd ralph && make buildPre-built binaries are available on the Releases page.
# Create a config file at ~/.config/ralph/config.toml
ralph init
# Set up a dotfiles repo
mkdir -p ~/.dotfiles
cp ~/.bashrc ~/.dotfiles/.bashrcAdd entries to your config:
dotfiles_repo_path = "~/.dotfiles"
[dotfiles.bashrc]
source = ".bashrc"
target = "~/.bashrc"
[shell.aliases.ll]
command = "ls -alhF"
[shell.aliases.g]
command = "git"Apply it:
ralph upRun it again and nothing changes. Run it after editing your config and only the diff gets applied.
For scripting, add -o json to get a machine-readable run report on stdout:
ralph up --no-sync -o json | jq '.summary'See Commands → JSON output for the document shape.
- Dotfiles -- symlink, copy, or template files from a source repo to their targets
- Directories -- create directories before other operations
- Git repositories -- clone, pull, pin to branch or commit
- Shell config -- aliases, functions, and environment variables injected into your rc file
- Build hooks -- run commands during apply (always, once, or manual)
- Packages -- clone remote tools or track local projects;
ralph upsyncs and rebuilds on changes - Tool checks -- verify tools are installed, show install hints
- Recipes -- split config into modular
recipe.tomlfiles alongside source files, ordered into dependency waves (ralph graphrenders the layout) - Remote recipe sources -- pull recipes from other git repos, so a project can ship its code and its install recipe together
- Machine profiles -- tag machines and recipes with roles (
personal,work, ...) and hostnames; only matching recipes apply
A repo can ship recipes next to its code and any machine can consume them.
Point a [[recipe_sources]] stanza at the repo:
[[recipe_sources]]
name = "thismoon"
url = "git@github.com:mad01/thismoon.git"
ref = "main"
update = trueralph clones the source into ~/.config/ralph/sources/<name>, discovers
recipe.toml files under its recipes/ directory, and merges them under the
namespaced identity <source>/<recipe> (here thismoon/reminder,
thismoon/csl, ...). A branch ref with update = true follows the branch on
every ralph up; a tag or commit ref pins. Machine-private wiring (secrets,
host config, overlays) stays in your own config repo as companion recipes
layered on top.
See Recipes → Remote sources for the full reference, and thismoon for a repo built around this pattern.
| Guide | Description |
|---|---|
| Getting Started | Zero to working setup |
| Commands | All commands with flags and examples |
| Configuration | Full config.toml schema reference |
| Recipes | Modular configuration with auto-discovery |
| Packages | Package management (ralph up) |
| Workflows | Daily usage patterns |
| Templating | Go template system for dotfiles |
| Migration | Symlink migration after reorganization |
| Example | Description |
|---|---|
| minimal | Simplest setup -- 3 dotfiles, 2 aliases |
| recipe-based | Modular config with auto-discovery |
| with-packages | Local and remote package builds |
| dotfiles-repo | Full dotfiles repository structure |
Releases are tag-driven: pushing a v* tag runs GoReleaser in CI, which
builds a darwin/arm64 binary (ralph targets macOS), embeds the version via
ldflags, and publishes a tar.gz archive with checksums and a changelog to the
Releases page.
Contributions welcome. Open an issue or PR on GitHub.
See LICENSE file.