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, anddelta - DevOps tooling including Kubernetes, Docker, Terraform, Helm, AWS, Azure, GitHub CLI,
uv, andmise
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
TABopens an interactivefzfcompletion menu with previews powered bybatandezadeltaprovides beautiful side-by-side Git diffszjumps to frequently used directories viazoxidesopens a fuzzy Kubernetes context picker usingkubeswitch
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-taborderingcompinitpermission 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
fzfalready 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