My Zsh Configuration: One Shell Across Every Machine

On this page Table of Contents

My Zsh Configuration: One Shell Across Every Machine

Over the years I’ve accumulated aliases, plugins, shell functions, and little quality-of-life improvements on every machine I use. Every new laptop meant copying pieces of old .zshrc files, trying to remember which plugin I installed years ago, and slowly ending up with different environments everywhere. Eventually I decided to stop maintaining multiple shell configurations and build one that works everywhere. The result is this repository: a modular, cross-platform Zsh configuration that I use every day on macOS, Arch Linux, Fedora, and other Linux systems. The goal is simple:

Every machine should feel exactly the same the moment I open a terminal.

It doesn’t matter whether I’m on my desktop, a laptop, a virtual machine, or a cloud instance, the same aliases, prompt, completions, tools, and workflows are always there.

Highlights

The configuration is built around Oh My Zsh and Powerlevel10k, together with a collection of modern command-line tools that I actually use every day. Some of the highlights include:

  • Cross-platform support (macOS, Arch, Fedora, and most Linux distributions)
  • XDG-compliant layout (~/.config/zsh)
  • Conditional plugin loading (plugins only load if the corresponding command exists)
  • Modern CLI replacements such as eza, bat, fzf, zoxide, direnv, and delta
  • DevOps tooling including Kubernetes, Docker, Terraform, Helm, AWS, Azure, GitHub CLI, uv, and mise

Everything lives in a single repository: https://github.com/aganet/zsh

What it looks like

The prompt is powered by Powerlevel10k, showing useful information without becoming noisy. Some of my favourite features are:

  • Git status directly in the prompt
  • Current Kubernetes context and namespace
  • Command execution time
  • TAB opens an interactive fzf completion menu with previews powered by bat and eza
  • delta provides beautiful side-by-side Git diffs
  • z jumps to frequently used directories via zoxide
  • s opens a fuzzy Kubernetes context picker using kubeswitch

The idea is to make common tasks fast without having to remember dozens of long commands.

Project structure

The configuration is intentionally split into small files.

pluginrc      Plugins
optionrc      Shell options and history
aliasrc       Aliases
local.zsh     Machine-specific overrides (git ignored)

Keeping everything modular means I can tweak one part of the shell without turning my .zshrc into a thousand-line file.

Installation

Getting started only takes a few minutes..

1. Clone the repository

git clone https://github.com/aganet/zsh.git ~/.config/zsh

touch ~/.zshenv
grep -qxF 'export ZDOTDIR="$HOME/.config/zsh"' ~/.zshenv || \
echo 'export ZDOTDIR="$HOME/.config/zsh"' >> ~/.zshenv

2. Install Oh My Zsh and Powerlevel10k

sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended --keep-zshrc

Install Powerlevel10k:

git clone --depth=1 https://github.com/romkatv/powerlevel10k.git \
${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k

Install the plugins:

  • zsh-autosuggestions
  • fast-syntax-highlighting
  • fzf-tab

(as shown in the repository).

3. Install the tools you actually use

The configuration automatically enables integrations for tools that are already installed. I personally install things such as:

  • eza
  • bat
  • fzf
  • fd
  • ripgrep
  • zoxide
  • delta
  • lazygit
  • direnv
  • tmux
  • Neovim
  • kubectl
  • Helm
  • Terraform
  • OpenTofu
  • Docker
  • GitHub CLI
  • AWS CLI
  • Azure CLI
  • uv
  • mise

You can install them using Homebrew, your Linux package manager, or any method you prefer. Because everything is guarded with command -v, missing tools simply disable their related aliases and plugins instead of producing errors.

4. Make Zsh your login shell

chsh -s "$(command -v zsh)"

5. Optional Git improvements

If you use delta, I recommend enabling it globally:

git config --global core.pager "delta"
git config --global interactive.diffFilter "delta --color-only"
git config --global delta.navigate true
git config --global delta.line-numbers true
git config --global delta.side-by-side true
git config --global merge.conflictstyle "zdiff3"

Everyday workflow

Some of the shortcuts I use the most are:

Key / Command Purpose
Ctrl-T Fuzzy file picker
Alt-C Jump to a directory
Ctrl-R Interactive history search
TAB fzf completion
z <dir> Jump with zoxide
s Kubernetes context picker
lazygit Git TUI
tldr Quick command examples
reload Reload the shell
update Update the system and tools

Examples

A few examples from my daily workflow.

Kubernetes

s
kctx prod
kns api
k get pods -A
kpf svc/myapp 8080:80

Navigation

z api
zi
nvim $(fzf)

Docker

dcu
dcl
dex web bash

Python

uvenv
uva fastapi httpx
uvr main.py
uvx ruff check .

Git

git diff
lazygit
ghpr
ghprs

Aliases

The repository contains aliases for:

  • Kubernetes
  • Docker
  • Docker Compose
  • Terraform
  • OpenTofu
  • Helm
  • AWS CLI
  • Azure CLI
  • GitHub CLI
  • Python (uv)
  • Git
  • System administration
  • Networking

Every alias group is conditionally loaded, so commands only exist when the corresponding software is installed.

Troubleshooting

Common issues are documented in the repository, including:

  • Nerd Font setup
  • fzf-tab ordering
  • compinit permission warnings
  • Startup performance profiling
  • Per-OS plugin loading
  • Updating kubeswitch
  • Reloading the shell after removing tools

Deliberately not included

There are a few popular tools I intentionally don’t use.

  • atuin — native history together with fzf already covers my workflow.
  • zsh-vi-mode — I prefer Emacs keybindings at the shell and Vim inside my editor.
  • starship — Powerlevel10k’s instant prompt is faster and integrates perfectly with the rest of my setup.

Sometimes choosing what not to install is just as important as choosing what to include.

Final thoughts

This isn’t meant to be another Zsh framework or plugin manager.

It’s simply the shell environment I’ve refined over years of daily use, shaped by the tools and workflows I reach for every day. Every alias, plugin, and shortcut is there because it solves a problem I actually have, not because it’s fashionable.

The biggest benefit isn’t any single feature it’s consistency. Whether I’m on my desktop, a laptop, a VM, or a freshly provisioned server, opening a terminal always feels familiar.

If you’re building your own shell configuration, I hope you find something useful here. Borrow whatever makes sense, ignore the rest, and make it your own.

The repository is open source under the MIT License. If it saves you from reinventing your .zshrc, then it’s already done exactly what I hoped it would.

Comments