youtube.nixfred.com nixfred.com

NEVER lose dotfiles again with GNU Stow

typecraft opens on a fresh Linux box with an ugly terminal and a bare Neovim, then restores his entire environment with one command using GNU Stow, a symlink farm manager that pairs with a git repository to deploy dotfiles to any Linux or macOS machine. He builds the idea from the ground up: a live ln -s demo showing that a symlink and its target are one coupled file, the Stow package naming convention that mirrors each config's path relative to $HOME (nvim/.config/nvim, zsh/.zshrc), and hands on demos stowing his real Neovim and tmux configs. The payoff is the loop: edit a config anywhere, the change flows through the symlink into the repo, commit and push, and every other machine syncs with a pull.

Published Jun 14, 2024 14:33 video 17 min read Added Aug 21, 2026 Open on YouTube →

At a glance

typecraft opens on a fresh Linux box with broken fonts, ugly colors, and a completely unconfigured Neovim, then runs one command and watches his entire environment snap into place: terminal gorgeous, Neovim perfect. The tool is GNU Stow, a symlink farm manager, and paired with a git repository it turns your dotfiles into something you can replicate on any machine, Linux or macOS, with a single command. The video builds the whole idea from the ground up: what Stow is, what a symlink actually is (demonstrated live with ln -s), the naming convention Stow expects, and then a real hands on demo stowing his Neovim and tmux configs. By the end you understand the full loop: edit a config anywhere, the change flows through the symlink into the repo, commit and push, and every other machine picks it up with a pull. This page rebuilds the whole tutorial, every command, every directory layout, and every joke, in the video's own order.

The one command demo

The video opens with the pitch, delivered at full typecraft energy: he has found the most amazing way to manage all of his dotfiles across all of his machines, and it does not even matter whether he is on Linux, which he uses Arch by the way, or macOS.

To prove it he shows the before state. He is on his Linux machine with essentially no dotfiles installed. The terminal is decent looking but the fonts are messed up and the colors, in his words, look like crap. He opens Neovim and it is completely unconfigured: it does not look very good and overall it is just a bad experience.

Then the trick. He runs one command, and it installs both his Alacritty configuration (Alacritty is the terminal emulator he uses) and his Neovim configuration immediately. He exits the terminal, reopens it, and everything looks gorgeous. Basically perfect. He opens Neovim and Neovim looks perfect too.

What is this amazing tool? It is called GNU Stow, and the rest of the video shows what it is, how it works, and why it is so awesome. Seriously, stick around.

What is GNU Stow?

So what is GNU Stow, how does it work, and why should you be interested in it? All great questions. Look at you, asking great questions and being handsome.

The motivation first. If you are anything like him, you have accumulated a certain set of tools over time as a software developer. When you switch between machines, maybe one machine breaks and you need a new one, or you get a new machine for work, you want your dotfiles and configurations set up as quickly as possible. GNU Stow is a game changer for exactly that.

The official definition, straight from the GNU Stow project: GNU Stow is a symlink farm manager which takes distinct packages of software and or data located in separate directories on the filesystem and makes them appear to be installed in the same place. For example, /usr/local/bin could contain symlinks to files within /usr/local/stow/emacs/bin, /usr/local/stow/perl/bin, and so on. His reaction to the docs choosing Emacs and Perl as the examples: "Man, these Emacs people in GNU, huh?"

The big picture, drawn out

To show how Stow transports dotfiles from one machine to another, he draws the whole system out on a whiteboard (the diagramming is done in Eraser, the video's sponsor). Start with a list of dotfiles. They could be large or small, but you have a bunch of different kinds:

All of these configuration files can live in a single dotfiles repository in git. GNU Stow then creates symlinks to manage those files on completely different computers. Say the repository is your dotfiles repo on GitHub. You can use it to add your dotfiles to any computer you want.

Take his macOS machine. Using Stow he can basically copy and paste all of his dotfiles onto the Mac from the repo, and the cool part is that because of how symlinks work, if he ever changes any of those files on the Mac, the changes can be committed straight back to the same repository. Now take a Linux machine: same principle exactly. You essentially copy and paste the same dotfile setup and repurpose it for the Linux box, all done with symlinks. Draw some arrows, one more arrow, and the picture is complete: with GNU Stow and git you can replicate your dotfiles on any machine, macOS or Linux, and probably even WSL on Windows, though he does not own a Windows machine with WSL to test it. He is sure you can do it like that too, though.

One repo, every machine: the loop he draws on the whiteboard dotfiles repo on GitHub .zshrc nvim/ (lua files, plugins) alacritty/ (colors, setup .toml) macOS machine git clone + stow ~/.config/nvim -> clone ~/.zshrc -> clone Linux machine (Arch, by the way) git clone + stow ~/.config/nvim -> clone ~/.tmux.conf -> clone clone, stow clone, stow edit, commit, push pull
Figure 1. The whiteboard system rebuilt. The dotfiles live once, in a git repository. Each machine clones the repo and runs stow, which plants symlinks from the expected home directory locations back into the clone. Because the files on each machine are symlinks rather than copies, an edit made anywhere lands in the clone, gets committed and pushed, and every other machine picks it up with a plain git pull.

The learn.typecraft.dev plug

Mid video, a word from the typecraft platform itself. By the way, nerds: the video you are watching was released days earlier, ad free, on learn.typecraft.dev. Members get videos early with accompanying material that is basically a full tutorial in and of itself. YouTube channel members get free memberships on the platform, thanks for being ride or die typecraft gang. Members also get full courses, at recording time one on Neovim and one on tmux, with a Linux course coming soon, plus community posts, special Discord access and roles, and all kinds of goodies. Alright, back to the video.

What is a symlink?

The whole scheme runs on symlinks, so he stops to answer the obvious question: what exactly is a symlink?

A symlink is a special file in Linux, or in Unix systems generally, that acts as a pointer to another location in the filesystem, or even across filesystems. It lets you access data from another location without having to duplicate that data. A typical use in Linux is exposing an executable buried deep in the filesystem at a more convenient path so you can run it more easily.

The ln -s demo, live

He demos it from scratch. In a directory called some-random-folder he has an executable file called echo-something.sh. Run it and it echoes out hello world. A pretty simple file.

Now, he does not want to type the whole some-random-folder path every time. He could move the file to his home directory, but then he would be duplicating data, and if the file lived in a GitHub repository he would be moving it out of the repository to a local spot, which he does not want either. This is the perfect use case for a symlink:

ln -s some-random-folder/echo-something.sh something.sh

Piece by piece: ln is the tool that creates links from one file to another in Linux. The -s option stands for symbolic, meaning it creates a symbolic link, a special file that just points to another file in the system. The first argument is the file to link to, and the second is the name the new link should get. He picks something.sh.

With the symlink created, he verifies it by listing the directory with the long flag, which shows links:

ls -l
# something.sh -> /home/chris/some-random-folder/echo-something.sh

Two things to notice in that output. The arrow shows exactly which file the link points at. And all the way on the left of the listing, the permissions string starts with an l: that l stands for link, marking the file as a pointer to the file specified on the right. Pretty cool, right? Now instead of typing the whole directory out, sh something.sh does the same thing as running the original, because it is linked to that file.

The part that matters later: linked files are married

Here is the property the entire dotfiles workflow depends on. He opens the symlink something.sh and edits it, changing the output to hello poops. Something professional like that. Run the link: it says hello poops. Now go look at the original file in some-random-folder, the one the symlink points to, and it has changed as well.

Interesting. These two files are married together. They are completely coupled: change one and the other one changes. That, he says, is something to keep in mind for later in the video, because it is exactly the mechanism that lets an edit on any machine flow back into the dotfiles repository.

A symlink is a pointer, not a copy ~/something.sh the symlink ls -l mode starts with "l" holds no data of its own ~/some-random-folder/ echo-something.sh the real file, the only copy echo "hello world" points to edit either path, the one real file changes: "married together"

ln -s some-random-folder/echo-something.sh something.sh

Figure 2. The ln -s demo as a picture. The symlink stores only a pointer, so reading or editing something.sh really reads or edits echo-something.sh. When he changed the link's contents to "hello poops," the original changed too, because there is only one file. This coupling is the engine of the whole dotfiles workflow: edit the config your machine uses and you have edited the repo's copy, because they are the same file.

GNU Stow and symlinks

Back to the amazing diagram, where the power of GNU Stow is now obvious. All GNU Stow really does under the hood is manage the creation and deletion, and a couple of other things, of symlinks. If you have a repository full of dotfiles, you can use Stow and the stow command to create symlinks in a smart way on all of your machines. On each machine, every file in your dotfiles is symlinked to the dotfiles repository that was cloned onto that machine.

That is the entire trick. No agent, no daemon, no sync service. A git repo holds the real files, and Stow plants the pointers where each program expects to find its config.

ApproachWhat you typeWhat can go wrong
Copy files by handOne cp per config, on every machine, every time anything changesCopies drift apart immediately; the repo goes stale the first time you tweak a setting locally
Manual symlinksOne ln -s per file or directory, with the full source and target paths spelled out each timeTedious and error prone at scale; you maintain the mapping in your head
GNU Stowstow nvim from the dotfiles directoryThe package layout IS the mapping; one command per tool, links created and removed for you
Figure 3. Why Stow beats both naive options. Copying duplicates data and breaks the edit anywhere loop. Raw ln -s works, as the demo showed, but you become the symlink manager. Stow derives every link from the directory structure of the package itself, which is what makes the one command install in the intro possible.

The GNU Stow naming convention

Now the practical part. He sets up an example dotfiles folder to stow away his dotfiles, with the eventual goal of pushing it up to git. Stow has conventions around how it stows dotfiles, and the naming convention is interesting, but once you understand it, it makes plenty of sense.

The rule: in your Stow directory, each dotfile set is named after a package, and inside that package you recreate the exact directory path where the config needs to live on the machine, relative to your home directory. Then everything can live underneath that.

He works through three examples, from most nested to simplest:

Package name, then the path the config expects, relative to ~ ~/dotfiles/ (the git repo) nvim/ .config/nvim/ (lua, plugins...) alacritty/ .config/alacritty/ (colors, .toml) zsh/ .zshrc $HOME (what the machine sees) ~/.config/nvim symlink into dotfiles/nvim/... ~/.config/alacritty symlink into dotfiles/alacritty/... ~/.zshrc symlink into dotfiles/zsh/.zshrc stow nvim stow alacritty stow zsh
Figure 4. The naming convention in one picture. A package's internal layout is a mirror of where its files must land relative to $HOME. Run stow <package> from the dotfiles directory and Stow walks the package tree and plants a matching symlink in the home directory for each entry. No mapping file, no configuration: the directory structure is the configuration.

Stowing the Neovim and tmux configs for real

Time to see it in practice. Everything in this section happens live on his machine.

Neovim first

He moves his real Neovim configuration, which currently lives under ~/.config/nvim, into the new nvim package he created in the example dotfiles folder, under its .config subdirectory. Looking inside the dotfiles folder confirms the shape: nvim contains .config, which contains nvim, which includes all of his Neovim configuration files.

And now the before state, recreated deliberately: because he just moved all his configuration files out of ~/.config/nvim and into the dotfiles directory, opening Neovim gives him a completely bare editor. There is nothing to it.

The fix is the whole point of the video. From the base of the dotfiles directory, type the stow command plus the name of the package to stow onto this computer:

stow nvim

Hit enter, and Stow links everything under the nvim package into the home directory. Which means ~/.config/nvim is now symlinked to the package's .config/nvim. He proves it by listing the config directory and searching for nvim:

ls -l ~/.config | grep nvim
# nvim -> ../example-dotfiles/nvim/.config/nvim

There is the nvim folder, and it is really just a symlink to example-dotfiles/nvim/.config/nvim. That is how GNU Stow works: super easy to move all of your configuration files into the Stow directory and then recreate the existing dotfile setup on any computer you have.

tmux, one more time, to get it in our brains

He runs the drill once more so it sticks, this time with tmux. He wants his tmux configuration in the example dotfiles repo, so he creates a new package, a top level directory in the dotfiles folder called tmux, and changes into it. His tmux configuration currently lives at the base of his home directory as ~/.tmux.conf, and since home is where it needs to end up, the file goes directly under the package: tmux/.tmux.conf.

With the config moved out, opening tmux shows a base tmux setup. Nothing interesting going on. Then, from the base Stow directory:

stow tmux
ls -la ~ | grep tmux
# .tmux.conf -> example-dotfiles/tmux/.tmux.conf

The .tmux.conf file is now symbolically linked to example-dotfiles/tmux/.tmux.conf. Awesome. Open tmux again and it is back to its original glory, the exact configuration he had built before he removed it from the machine, put back using symlinks.

Closing the loop: edit anywhere, commit, pull everywhere

Now the payoff of the "married files" property from the symlink section. Say you want to change something in one of your configuration files, for example one of your Neovim plugins. Change the plugin file locally, and because it is symlinked, the change also lands where the link points: the dotfiles folder gets those changes too. So on any computer where your dotfiles are deployed with Stow, any edit you make can be committed right back to the GitHub repo, and all the rest of your computers get every change the moment they pull the repo down.

That is managing your dotfiles from anywhere, for every computer. His verdict, verbatim: GNU Stow truly is a game changer when it comes to managing dotfiles and managing different computers and configurations throughout your life. I love it. I think it is amazing. His own dotfiles repository is linked below, so check that out. And hey, thanks nerds.

Key takeaways

Chapters

Notable quotes

Resources mentioned

Full transcript
I have found the most amazing way to manage all of my DOT files across all of my machines and it doesn't even matter if I'm using Linux which I use Arch by the way or Mac OS seriously check this out right now I'm on my Linux machine and I don't have any dot files really installed I have a decent looking terminal but my fonts are messed up and my colors look like crap also if I open neovim neovim is completely unconfigured it doesn't look very good and overall it's just a bad experience but if I just run one Comm and I can install my alacrity which is the terminal I'm using and my neovim configs immediately now if I exit and then reopen my terminal everything looks gorgeous this is basically perfect now if I open up neovim neovim looks perfect as well what is this amazing tool it's called G sto I'm going to show you what it is how it works and why it's so awesome seriously stick around [Music] okay so what is Gano how does it work and why should I be interested in it well these are all great questions so look at you asking great questions and being handsome well if you're anything like me you've accumulated a certain set of tools over time as a software developer and if you want to switch between machines maybe let's say one machine breaks and you need a new one or let's say you get a new machine for work something like that you want to have your dot files and your configurations all set up as quick quickly as possible and gnu sto is a game changer that will help you achieve that very thing so what is ganu STO well ganu sto is a Sim link Farm manager which takes distinct packages of software and or data located in separate directories on the file system and makes them appear to be installed in the same place for example user local bin could contain Sim links to files within user local sto emac bin user local sto Pearl bin etc etc man these emac people in ganu huh so let's go over really quickly how ganu St works and how it's able to transport your dot files from one machine to another easily using Sim links let's draw it out really quick let's say you have a list of dot files now your dot files could be large could be small whatever but you have a bunch of different kinds of dot files now these dot files could include anything like your zshrc file your neovim configuration and within your neovim configuration you might want Lua files plugins Etc and then also possibly even like your terminal configuration for me that's El laity and within El laity you have like a color scheme and your actual like setup. Tomo file all of these configuration files could live in a files repository in git and you can use G sto to create Sim links to manage these files on completely different computers so let's just say that this is now your Gano GitHub repo right you can use this Gano GitHub repo to add your dot files to any computer you want now let's say this computer is my Mac OS machine now I can basically copy and paste all of my do files to this Mac OS machine from G stove and the cool thing is because of how Sim links work if I ever change any of these on my Mac OS machine they could also be committed to this gnu sto repository I'll show you how that works in a second now let's say I have a Linux machine well using gnu sto it's basically the same principles you essentially copy and paste this dot file setup here and you kind of repurpose it for your Linux machine and this is all done using Sim links just draw some arrows here and one more Arrow here so using G sto and Git You Can replicate your do files on any machine that's Mac OS or Linux probably even WSL on Windows but I don't really own a machine that has WSL on Windows I'm sure you can do it like that too though by the way nerds this video that you're watching right now was released days ago adree on our new platform it's called learn. typecraft dodev for all members of this platform this video was released adree with accompanying material that's basically a full tutorial in and of itself this website is awesome seriously you should check this out also for all our members in YouTube guess what you get free memberships thanks for being ride or die typecraft gang you're awesome but again if you want to be a member sign up at learn. typecraft dodev you're going to get videos early with accompanying tutorial material and they're all going to be ad free you also get full courses as of right now we have one on neovim one on t-o one on Linux coming up soon and you get all kinds of goodies like Community posts special access to Discord servers and rolls it's awesome seriously check it out all right let's get back to the video all right so we went over really quick about G stow and how you can use stow and GitHub to manage do files across all of your machines but we've talked about doing this with Sim links and you might be asking yourself what exactly is a Sim link a Sim link is a special file in Linux or in Unix systems that acts as a pointer to another location in the file system or even across file systems this enables you to access data from another location without having to duplicate that data now typically in Linux systems you would use sim links to move executables from a deep folder somewhere in your file system maybe to a path that allows you to execute it a little bit easier so let's say that in this folder here some random folder I have an executable file that file is called Echo something. sh if I run this file it just Echoes out hello world it's a pretty simple file as you can see but let's say I don't really want to run this file using the directory some random folder I could move this file to my home directory but then I'd be duplicating the data or if this was in a GitHub repository I'd be moving it out of the GitHub repository to a local spot and I don't really want to do that this is the perfect use case for something like a Sim link now Now to create a Sim link to this file this is what you'd have to do we want to type Ln which is a tool that lets you create links from one file to another in Linux you want to type the S option which stands for symbolic which means we're going to create a symbolic link which basically means it's going to be a special file that just points to another file in the system then we want to specify the file we want to link to this is going to be some random folder echos something. sh and then the second option is the file we want to call this let's just call this I don't know something Dosh that's going to be our Sim link is something Dosh to the echo something file now our Sim link is created we can check by Ling our current directory with the L flag which will show links now if we type this we can see that something. sh down here is linked to home Chris some random folder echos something. sh also you can check all the way on the left here this L stands for link that means that this file is a link to the file that's specified over here pretty cool right anyways now instead of having to type the whole entire directory out we can just sh something. sh and that will do the same thing that is done in echos something. sh it is linked to that file but here's something cool about Sim links if I now modify my something Dosh file let's say I go I don't know hello poops something professional like that right if I run this file it will say hello poops now if I go to some random folder and look at the original file that's linked via Sim link I can see that this file changed as well interesting so these two files are married together they're completely coupled if I change one the other one changes that's something to keep in mind for later on in this video so now if we go back to our amazing diagram here we can see the power of gnu Stow all ganu Stow really does under the hood is manage the creation and deletion and a couple other things of sim links so so if you have a repository full of sim links you can use G stow and the Stow command to create Sim links in a smart way on all of your machines now on each machine each file that's in your dot files let's say will be Sim linked to your dot files repository that was cloned onto that machine Let's show off how this works now with G sto now let's just say I have an example do files folder here that I want to use sto with to stow away all of my DOT files and eventually put it up on get now G sto has some conventions around how it stows away dot files essentially what you want to do is you want to name your dot files now the naming convention for guse though is interesting but once you understand it it makes plenty of sense let's go over it like this if you have a DOT file and your dot file exists in your machine as let's say something like I don't know let's go with neovim for example right it will exist in somewhere Inc config neoven now when it comes to G Stow we want to name this accordingly right so in G Stow we will expect that dot file to be named after a package and then have the same directory that you want it to exist with on that machine Let's show off what this looks like so for do config envm in our gnu Stow directory we want to create a new package let's call it envm and within envm we want to create the directory that we want that file or package to live on on our machine so that would be docum fig SL envm and then everything can live underneath that that is how you would name something in Gano let's do one more example let's say we want to copy over our I don't know our alacrity files right alacrity configurations live in config alacrity alacrity is the terminal emulator I've been using on Arch I use Arch by the way now in good news Stow the way you would name this alacrity package is very similarly to Neil VM you want to name a new package and then you want to recreate the config directory that elac needs to live with in your computer okay now let's just do one more that's like super simple let's talk about zshrc our zshrc just exists basically in the home directory as a DOT file pretty simple stuff in G Stow you want to create a new package called zsh and name our DOT file exactly where it needs to go which is our home zshrc simple cool awesome okay now let's do this let's see what it looks like in practice now we want to move our neovim configuration which currently lives under config neovim to the new envin package we created under the config subdirectory okay great so now if we look into our DOT files here we can see that in envm we have do config which has envm which includes all of our neovim configuration files okay great if I open neoen because I just moved all of my configuration files into this new directory that's using G sto you can see that neovim is completely bare there's nothing to it but using G sto all we have to do is type the Stow command in the name of the package we want to Stow onto this computer which for us is envm that's how it works with the naming convention if we do St envm and hit enter this will move everything under the envm directory to the home directory on our computer which means that we are now Sim linking config envm to our homes. config envm we can check this by going to our homes. config directory and now checking using ls- L and searching for envm let's see yes now we have an envm folder here which is really just a Sim link to our example. files env. config envm that's how good new St works it's super easy to move all of your configuration files over to Gano and then to just recreate this existing dot file configuration on any computer that you have so now let's just do one more example just to kind of repeat this so we get this in our brains a little bit better let's say that I want my t-o configuration to live in my example do files repo here so now let's say we want to copy our t-o configuration from where it lives in right now to our Now new Gano do files we want to create a new package which is t-mo that's what we want to call this here this is the top level directory within our Gano do files directory and underneath this let's just CD into it now we want to move our t-o configuration which currently lives at our base home directory t-mo.com to this directory right here because we want it to just be in our home directory so underneath this package we just want to call this t-mo.com okay simple now that I've moved my t-mo configuration over if I open t-o this is a base t-x config there's nothing interesting going on here but again if I type in my base G sto directory sto t-u and we search for everything under that directory and we pipe it to GP to t-mo we can see now that our t-mo.com file is symbolically linked to example do files t-mo tmo.com awesome now if we open up t-mo we can see that t-mo is back to its original Glory this is the t-mo configuration that I had configured before I removed it from my machine and now G St put it back on my machine using using Sim links and so let's just say that we want to change something in one of our configuration files let's say that our neovim configuration we want to change one of our plugins right if we change one of these plug-in files locally what'll happen is it will also change things where it's Sim link so our example do files folder will also get those changes so any computer that I have my do files on using G Stow using Sim links if I change those at all I can recommit them now to my G Hub repo and all the rest of my computers as long as I just pull down the git repo will have all these new changes so you can manage G sto dot files from anywhere for any computer gell truly is a game changer when it comes to managing dot files and managing different computers and configurations throughout your life I love it I think it's amazing I have a Gano do files repository linked down below so check that out and hey thanks nerds [Music]