Lnk: Simplify Your Dotfiles with a Git-Native CLI
· git
Dotfiles setups all collapse into the same thing: a pile of bash scripts held together by hope and ln -s commands nobody remembers writing. You provision a new VM, spend thirty minutes hunting for your .vimrc, realize the symlink script doesn’t work on macOS, fix it, break something else. Repeat forever.
I got tired of the cycle. So I built Lnk.
The Problem Is Always the Same
Let’s talk about what dotfile management actually looks like in practice. You start with a Git repo. You write some symlink logic. Maybe a Makefile. Then you need host-specific configs, so you add branching or environment variables or both. Then you get a new laptop and the bootstrap is manual because you forgot to script half of it. Then you switch to a tool that promises to fix everything and instead introduces YAML templating and a dependency on Ruby.
But here’s the thing. Dotfiles are just files. They live in known locations. They need symlinks. They need version control. They occasionally need per-machine overrides. That’s it. Four requirements. Why does every solution turn this into a distributed systems problem?
Lnk does exactly those four things:
- Move files safely into a centralized repo.
- Create portable, relative symlinks so nothing breaks if you clone somewhere else.
- Support host-specific overrides without forcing you to juggle dozens of branches.
- Run bootstrap scripts automatically when you clone or update.
Git plus symlinks plus a little bootstrap magic. Simple is a superpower.
What This Actually Solves
No more manual symlinks. Instead of ln -s commands scattered across README files that nobody reads, Lnk handles everything automatically. Add a file, it moves into ~/.config/lnk, symlink goes back where it belongs. Done.
Host-specific configs that don’t bite. Work SSH keys go in one subfolder, laptop tmux settings in another. Lnk treats them as first-class citizens. No scripting around weird directory names. No environment variable gymnastics.
Bootstrap scripts that actually run. Clone your dotfiles on a new machine, and if there’s a bootstrap.sh, Lnk executes it immediately. No more “I forgot to install my Vim plugins” twenty minutes into a pairing session.
Git-native workflow. You still use git add, git commit, git push. Nothing exotic. If you know Git, you already know how Lnk works.
Why do so many tools promise “one-size-fits-all” and then make your life genuinely harder? Lnk cuts the fluff. One job. Done well.
How to Install Lnk
Pick whichever path makes sense for you.
Quick Install (Recommended)
curl -sSL https://raw.githubusercontent.com/yarlson/lnk/main/install.sh | bashOne command. Lnk lands in /usr/local/bin. It auto-detects your OS (Linux, macOS, Windows under Git Bash) and fetches the latest release.
Homebrew (macOS/Linux)
brew tap yarlson/lnk
brew install lnkHomebrew handles everything, including updates. Just brew upgrade lnk when you want new features.
Manual Download
# Linux x86_64 example
wget https://github.com/yarlson/lnk/releases/latest/download/lnk_Linux_x86_64.tar.gz
tar -xzf lnk_Linux_x86_64.tar.gz
sudo mv lnk /usr/local/bin/Substitute the URL for your platform (arm64, Windows, etc.) if needed. After that, lnk --version should print something like v1.0.0.
Getting Started
Open a terminal. Run this:
lnk initThat creates ~/.config/lnk and initializes it as a Git repo. From there, Lnk is ready. Let’s talk about the actual workflow.
1. Initialize Your Dotfiles Repo
-
Start from scratch (no remote):
lnk initSets up your local repo in
~/.config/lnk. Nothing more. -
Clone an existing repo (and run bootstrap):
lnk init -r [email protected]:you/dotfiles.gitLnk clones your dotfiles straight into
~/.config/lnk. If it finds abootstrap.sh, it kicks off your machine setup automatically. -
Skip bootstrap (run it later):
lnk init -r [email protected]:you/dotfiles.git --no-bootstrap
2. Add Files to Be Managed
-
Common config (shared across all machines):
lnk add ~/.vimrc ~/.bashrc ~/.gitconfigLnk moves each file into
~/.config/lnk, commits it to Git, and leaves a symlink at the original path. Edit~/.vimrclike nothing changed. Lnk stays out of your way. -
Host-specific config (machine-specific overrides):
lnk add --host work ~/.ssh/config ~/.tmux.confSSH config and tmux settings land in
~/.config/lnk/work.lnk/, symlinked back to their home paths only if your hostname matches “work.” Your laptop gets its own files underlaptop.lnk/. No clashes. No drama.
3. Commit & Push
lnk push "Initial config commit"Under the hood, Lnk stages everything, commits with your message, pushes to the remote. No more juggling git add -A inside a hidden folder.
4. Pull & Sync on a New Machine
lnk init -r [email protected]:you/dotfiles.git
# → runs bootstrap automatically if present
lnk pullLnk fetches the latest commits, updates your local Git copy, restores symlinks. Host-specific files? Add --host laptop and Lnk pulls those too.
5. Run Bootstrap Manually
Skipped bootstrap during init? Run it whenever:
lnk bootstrapExecutes bootstrap.sh inside your dotfiles repo. Packages, plugins, whatever you’ve scripted.
Tips & Tricks
-
Check status:
lnk statusLike
git status, but aware of your symlinks. Shows local changes and whether you’re ahead or behind the remote. -
List managed files:
lnk list # common only lnk list --host work lnk list --all # everythingFor when you forget what Lnk is tracking. You will forget.
-
Remove a file:
lnk rm ~/.vimrcMoves the file back to your home directory, deletes the symlink, updates the Git index. Clean.
Why This Feels Different
Look, you could clone a bare repo and write symlink scripts yourself. I’ve done it. Repeatedly. Every time, I ended up writing another helper that half-broke on macOS, or I forgot git update-index --assume-unchanged on some file, and chaos followed.
Lnk eliminates that entire category of problem. It abstracts away platform-specific quirks. It keeps symlinks relative, so you can move your dotfiles folder anywhere and nothing breaks. It isolates host configs so your office workstation’s secrets never bleed into your personal laptop.
Someone asks “How do I sync my dotfiles?” and instead of a ten-minute explanation involving merge strategies, you say “lnk init on the new box.” Conversation over before the coffee’s done.
Dotfile management doesn’t need to be clever. It needs to be boring and reliable. Lnk is genuinely both. It works across Linux, macOS, WSL. It does one thing, and it does it well. That’s the whole pitch.
Give it a try: github.com/yarlson/lnk
