← All projects

Dotfiles: One-Command Terminal Environment

The problem

Setting up a new machine is painful. Install the terminal, configure the shell, set up the editor, install tools, configure themes, remember aliases. Every developer does this dance, and most lose hours getting things "just right" only to forget what they did when the next machine comes along.

I wanted to run one command and get my entire environment, exactly as I left it, on any machine.

What I built

An open source dotfiles repository managed with GNU Stow that installs and configures a complete terminal environment with a unified Catppuccin Mocha theme. One command, everything configured, idempotent and safe to re-run.

The journey

This started as a backup of my .zshrc. It grew into a curated replacement for nearly every default CLI tool.

What's inside

Category Tool What It Does
Terminal Ghostty GPU-accelerated terminal (fastest on macOS)
Shell Zsh + Zinit Fast shell with async plugin loading
Prompt Starship Git, language, and time context in prompt
Multiplexer tmux Split panes, persistent sessions
Editor Neovim Full IDE with LSP, autocomplete, fuzzy finder
Navigation zoxide Smart cd that learns your directories
File Manager yazi Terminal file browser with previews
History atuin SQLite-backed searchable command history
Git lazygit + delta Visual git TUI + beautiful diffs

Modern CLI replacements

Every old command aliased to a faster, better alternative:

You Type Actually Runs Upgrade
ls eza Icons, colors, git status
cat bat Syntax highlighting
rm trash Sends to trash (safe delete)
vim nvim Neovim with IDE features

Plus ripgrep (rg), fd, dust, sd, and btop installed under their own names to avoid breaking scripts.

What building this taught me

1. GNU Stow is elegantly simple

I tried symlink scripts, Ansible playbooks, and Nix. All overkill. GNU Stow does one thing: mirror a directory structure as symlinks. Each tool gets its own directory, stow toolname creates the links, stow -D toolname removes them.

dotfiles/
├── zsh/
│   └── .zshrc          → ~/.zshrc
├── tmux/
│   └── .tmux.conf      → ~/.tmux.conf
├── nvim/
│   └── .config/nvim/   → ~/.config/nvim/
└── starship/
    └── .config/starship.toml → ~/.config/starship.toml

No templating language, no dependency resolution, no abstractions. Just filesystem conventions.

2. Theme consistency matters more than individual tool choices

Having Catppuccin Mocha across every tool (terminal, editor, tmux, git diffs, file manager) creates a surprisingly cohesive experience. The tools themselves matter less than them looking and feeling like they belong together.

3. Idempotent installers prevent anxiety

The installer backs up existing configs before overwriting. Running it twice does the same thing as running it once. This seems obvious, but most dotfile setups fail on re-runs. Making it safe to re-run meant I actually ran updates instead of letting configs drift.

4. Aliasing carefully avoids breaking things

I alias ls to eza because nothing breaks. But I don't alias grep to ripgrep because shell scripts depend on grep's exact flags. The principle: alias interactive commands, leave scriptable commands alone.

The bigger realization

Developer tooling is personal infrastructure. The hours invested in a good terminal setup pay dividends every single day. But the real value isn't the tools; it's the reproducibility. Knowing I can go from a blank machine to my full environment in under 10 minutes removes friction from everything else.

What I would do differently

Add a machine-local config layer from the start. Some settings are universal (theme, aliases), but others are machine-specific (work vs. personal git email, proxy settings). I'd separate these earlier instead of manually editing after install.

References

Links

Let's build something together.

Got an idea? I'm always up for a new challenge, whether it's a side project, a startup, or something in between.

© 2026 Cyrus David Pastelero. All rights reserved.

Built with Next.js, TypeScript & Tailwind CSS