Zsh (Z Shell) has become increasingly popular among developers due to its powerful features and extensive customization capabilities. This guide will walk you through setting up a fast, efficient, and feature-rich Zsh configuration that avoids common performance pitfalls.
Apidog combines API documentation, debugging, and automated testing in one platform with a more intuitive interface and better team collaboration features.
The import functionality makes switching from Postman seamless, and many developers report faster workflows with its mock servers and environment management. The free tier is quite generous, making it accessible for individual developers and small teams.
Give Apidog a try alongside your new Zsh configuration for a completely refreshed development environment!
Why This Zsh Configuration Performs Better
The approach I'll outline offers several advantages over traditional setups:
- Significantly faster startup times (0.03-0.07s vs 0.5-1.0s with basic Oh My Zsh)
- Modern plugin management with better performance characteristics
- Lazy loading of resource-intensive components
- Cleaner configuration structure that's easier to maintain
How to Use this Zsh Config (2 Options)
You have several choices for your Zsh framework, each with different trade-offs:
Option 1: Zinit + Powerlevel10k (Advanced, Best Performance)
Zinit is a powerful plugin manager that allows asynchronous loading and offers exceptional performance.
- Install Zsh first:
# For Ubuntu/Debian
sudo apt install zsh
# For macOS with Homebrew
brew install zsh
# For Fedora
sudo dnf install zsh
2. Make Zsh your default shell:
chsh -s $(which zsh)
3. Install Zinit:
bash -c "$(curl --fail --show-error --silent --location <https://raw.githubusercontent.com/zdharma-continuum/zinit/HEAD/scripts/install.sh>)"
4. Create your .zshrc
configuration:
# Enable Powerlevel10k instant prompt (makes shell appear instantly)
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi
# Load Zinit
source "$HOME/.local/share/zinit/zinit.git/zinit.zsh"
# Load Powerlevel10k theme
zinit ice depth=1
zinit light romkatv/powerlevel10k
# Core zsh functionality (history, completion)
zinit snippet OMZL::history.zsh
zinit snippet OMZL::completion.zsh
zinit snippet OMZL::key-bindings.zsh
# Essential plugins with async loading (turbo mode)
zinit wait lucid for \\\\
atinit"zicompinit; zicdreplay" \\\\
zdharma-continuum/fast-syntax-highlighting \\\\
atload"_zsh_autosuggest_start" \\\\
zsh-users/zsh-autosuggestions \\\\
zdharma-continuum/history-search-multi-word
# Git plugin from Oh My Zsh - loaded when entering a git repository
zinit ice wait lucid
zinit snippet OMZP::git
# Load Node version manager only when needed
export NVM_LAZY_LOAD=true
export NVM_COMPLETION=true
zinit ice wait lucid
zinit light lukechilds/zsh-nvm
# Starting directory
cd ~/repos
# Source aliases from a separate file for better organization
[[ -f ~/.zsh_aliases ]] && source ~/.zsh_aliases
# Configure Powerlevel10k
POWERLEVEL9K_PROMPT_ADD_NEWLINE=true
POWERLEVEL9K_MODE='awesome-fontconfig'
POWERLEVEL9K_BATTERY_SHOW=false # Turn off battery status
POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(dir vcs)
POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(status time background_jobs)
# Initialize Powerlevel10k
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh
5. Configure Powerlevel10k:
After restarting your terminal, Powerlevel10k's configuration wizard will automatically start. Follow the prompts to customize your prompt appearance.
If you need to reconfigure later, run:
p10k configure
Option 2: Zim (Simpler, Still Fast)
Zim is a more user-friendly yet still very fast Zsh framework that offers a great balance of features and performance.
- Install Zsh (same as above)
- Install Zim:
curl -fsSL <https://raw.githubusercontent.com/zimfw/install/master/install.zsh> | zsh
- Edit your
.zimrc
file to add modules:
# Core
zmodule environment
zmodule git
zmodule input
zmodule termtitle
zmodule utility
# Prompt
zmodule romkatv/powerlevel10k
# Completion
zmodule zsh-users/zsh-completions
zmodule completion
# Modules that must be initialized last
zmodule romkatv/zsh-defer # For async loading
zmodule zsh-users/zsh-syntax-highlighting
zmodule zsh-users/zsh-autosuggestions
zmodule zsh-users/zsh-history-substring-search
- Create your
.zshrc
file:
# Enable Powerlevel10k instant prompt
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi
# Initialize zsh-defer for async loading
source ${ZIM_HOME}/modules/zsh-defer/zsh-defer.plugin.zsh
# Start ZIM
if [[ ! ${ZIM_HOME}/init.zsh -nt ${ZDOTDIR:-${HOME}}/.zimrc ]]; then
# Update static initialization script if it does not exist or is outdated
zsh-defer source ${ZIM_HOME}/zimfw.zsh init -q
fi
source ${ZIM_HOME}/init.zsh
# Customize key bindings
bindkey '^[[A' history-substring-search-up
bindkey '^[[B' history-substring-search-down
# Lazy load Node version managers
if command -v fnm &> /dev/null; then
zsh-defer eval "$(fnm env --use-on-cd)" # Use fnm (faster alternative to nvm)
elif command -v nvm &> /dev/null; then
zsh-defer source $(brew --prefix nvm)/nvm.sh # Only load nvm when needed
fi
# Starting directory
cd ~/repos
# Source aliases
[[ -f ~/.zsh_aliases ]] && source ~/.zsh_aliases
# Load powerlevel10k configuration
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh
Creating a Better Aliases File
Instead of embedding all aliases directly in your .zshrc
, create a separate .zsh_aliases
file for better organization:
# Create a .zsh_aliases file
touch ~/.zsh_aliases
Here's an improved version of the aliases with better organization:
# File operations
alias rmrf='rm -rf'
alias ls='ls -lart --color=auto'
# Directory navigation
alias r='cd ~/repos'
alias ..='cd ..'
alias ...='cd ../..'
alias ....='cd ../../..'
# Development environments
alias c='code .'
alias s='cursor .'
alias e='exit'
# Git operations
alias g='git'
alias gs='git status'
alias ga='git add .'
alias gc='git commit -m'
alias gagc='git add . && git commit -m'
alias gp='git fetch -p'
alias gcom='git checkout main'
alias gcol='git checkout -'
alias gb='git checkout -b'
alias gbl='git branch -a'
alias grv='git remote -v'
alias grb='npx git-removed-branches'
alias gcl='git clone'
alias gbr='git browse'
alias pp='git pull --rebase && git push'
# Package management - npm
alias ni='npm i'
alias nid='npm i -D'
alias nig='npm i -g'
alias nr='npm run'
alias nrb='npm run build'
alias nrd='npm run dev'
alias nrs='npm run start'
alias nlg='npm list -g --depth=0'
# Package management - yarn
alias ya='yarn add'
alias yad='yarn add -D'
alias yb='yarn build'
alias yd='yarn dev'
alias ys='yarn start'
alias yyb='yarn && yarn build'
alias yyd='yarn && yarn dev'
alias ylg='yarn global list'
# Package management - pnpm
alias pi='pnpm i'
alias pid='pnpm i -D'
alias prb='pnpm run build'
alias prd='pnpm run dev'
alias prs='pnpm run start'
alias plg='pnpm list -g --depth=0'
alias pc='pnpm create'
# Development tools
alias kill='npx kill-port'
alias di='echo dotenv > .envrc && touch .env && direnv allow'
alias tdl="tree -a -I 'node_modules|.svelte-kit|.git' --dirsfirst"
Performance Optimization Tips
- Use lazy loading for heavy components
- Node version managers (nvm, fnm) are major slowdown culprits
- Use
zsh-defer
or Zinit's turbo mode to load them asynchronously
- Cache eval outputs with evalcache
- Install:
zinit light mroth/evalcache
- Replace
eval "$(command)"
with_evalcache command
- Consider fnm instead of nvm
- fnm is a Rust-based alternative that's much faster
- Install:
brew install fnm
orcurl -fsSL <https://fnm.vercel.app/install> | bash
- Minimize plugins
- Only use plugins you actually need
- Choose modern, optimized plugins (like fast-syntax-highlighting over zsh-syntax-highlighting)
- Use Powerlevel10k's instant prompt
- Makes your shell appear instantly while loading continues in background
- Split configuration into multiple files
- Keep
.zshrc
clean and modular - Use separate files for aliases, functions, and environment variables
Measuring Your Shell's Performance wth the New Zsh Config
Add this function to your .zshrc
to check your shell's startup time:
function timezsh() {
shell=${1-$SHELL}
for i in $(seq 1 10); do
/usr/bin/time $shell -i -c exit
done
}
Then run timezsh
to see your average startup time.
Conclusion
By using modern tools like Zinit or Zim, implementing lazy loading, and organizing your configuration properly, your Zsh experience will be significantly faster and more pleasant to use. The approaches outlined here represent current best practices that balance functionality with performance.
Remember that shell configuration is highly personal - feel free to experiment with these suggestions and adapt them to your specific workflow and preferences.
Apidog combines API documentation, debugging, and automated testing in one platform with a more intuitive interface and better team collaboration features.
The import functionality makes switching from Postman seamless, and many developers report faster workflows with its mock servers and environment management. The free tier is quite generous, making it accessible for individual developers and small teams.
Give Apidog a try alongside your new Zsh configuration for a completely refreshed development environment!