← Back to all posts

My dotfiles, one line

Every fresh install used to start the same way: a folder of half-remembered configs, a dozen tabbed tutorials, and a .bashrc pasted together at 1 AM. Now the whole ritual is one line:

curl -fsSL https://potaterrr.github.io/install | sh

Bash, Neovim, Starship, Fastfetch โ€” and if you want them, Hyprland, Waybar, Wofi and GTK โ€” installed and wired into $HOME on a pick of six distro families. Here's how the script works and why piping curl into sh is less scary than it looks, as long as the script earns the pipe.

Two scripts, two jobs

The URL serves a tiny POSIX bootstrap. Its whole job is to clone (or update) the dotfiles repo and hand off to the real installer, install.sh. Keeping the bootstrap small matters: it's the only part a first-time visitor runs sight-unseen from the page, so it stays short enough to audit in one screen.

The second stage is where the work happens. It detects your package manager โ€” apt, dnf, pacman, zypper, apk or xbps โ€” maps logical package names to distro-specific ones, installs dependencies, then lays configs into place with GNU Stow.

Don't run scripts blindly

  • curl -fsSL: -f fails on HTTP errors instead of piping an error page into a shell, -S surfaces download errors, -L follows the redirect GitHub Pages issues.
  • The bootstrap needs git and bash, and says so instead of failing mid-way.
  • Re-running is safe: an existing clone is updated with git pull --ff-only, never reset or overwritten.
  • Where to clone is configurable (DOTFILES_BASE) โ€” nothing assumes to own your home directory.

And the golden rule: read the script first. It's linked right next to the install command for exactly that reason.

Why GNU Stow

Stow treats every config as a package โ€” bash/, nvim/, hypr/ โ€” each a little tree of files laid out the way they should land in $HOME. Installing a package means symlinking that tree into the target directory. The payoff:

  • Per-package install and removal. Want Waybar but not Hyprland? Tick two boxes in the menu.
  • Every deployed file is a symlink. Edit the repo, and home follows. No drift between "my config" and "the config that's deployed".
  • Updates are a pull. git pull then re-stow โ€” or just rerun the one-liner, which does both.

One real-world wrinkle: fresh distros ship files like ~/.bashrc from /etc/skel, and stow refuses to replace real files with links. The installer detects those collisions first and moves them aside to .bashrc.pre-stow.<timestamp> โ€” with a guard so it never backs up anything that already resolves inside the repo itself.

A menu, not a leap of faith

When run interactively, a whiptail checklist lets you pick exactly what to install; the defaults cover the daily drivers. On machines without whiptail there's a plain numbered menu, and for CI-style no-TTY runs it installs the default set and says so loudly. Piping from curl shifts stdin, so the bootstrap hands the installer /dev/tty โ€” without that detail, the interactive menu would eat the pipe and die.

Try it

Read the installer, then run it. If anything gets backed up along the way, it tells you where it went. Worst case, delete the symlinks and move the .pre-stow files back โ€” nothing is ever lost.