The default terminal setup on most systems works well enough to get things done, but it leaves a lot on the table. Bash handles scripting and interactivity, but its autocompletion is basic, its prompt customization is limited, and there is no plugin system to extend it without manual configuration.
Zsh addresses most of those limitations, and Oh My Zsh makes Zsh's configuration manageable. The combination is widely used in professional development environments for good reason: it is faster to work in, more informative at a glance, and easier to extend than a default Bash setup.
This guide covers the full setup from installation through to personalization, with the plugins and shortcuts that are actually worth using.
What this covers:
What Zsh and Oh My Zsh are and how they differ from Bash
Installation on macOS and Linux
Configuring themes, including Powerlevel10k
Essential plugins and how to enable them
Useful keyboard shortcuts
Aliases and environment variables
What Zsh Adds Over Bash
Zsh is a Unix shell that builds on Bash and extends it in several practical directions. The differences that matter most for daily development work:
Autocompletion is context-aware and applies to commands, paths, flags, and arguments rather than just filenames
Spelling correction catches typos in command names before running them
Command history is shared across open terminal sessions rather than being session-specific
Globbing and path expansion are more powerful for scripting and file operations
Zsh has been the default shell on macOS since Catalina (10.15). On most Linux distributions it is available through the package manager but not set as the default.
What Oh My Zsh Adds Over Zsh
Oh My Zsh is a framework that manages Zsh configuration. Rather than writing and maintaining .zshrc settings by hand, Oh My Zsh provides a structured way to enable plugins, switch themes, and keep the configuration readable.
What it includes out of the box:
Over 250 themes for customizing the prompt
A large library of plugins for common developer tools
An update mechanism that keeps the framework and plugins current
Compatibility across macOS, Linux, and Windows via WSL
The comparison to Bash is worth making explicit:
Feature | Bash | Zsh with Oh My Zsh |
|---|---|---|
Autocompletion | Basic | Context-aware |
Prompt customization | Limited | Extensive via themes |
Plugin support | Manual | Built-in plugin manager |
Git integration | None by default | Available via plugin |
Syntax highlighting | No | Available via plugin |
Auto-suggestions | No | Available via plugin |
Step 1: Install Zsh and Oh My Zsh
Install Zsh
On macOS with Homebrew:
brew install zsh
On Ubuntu or Debian:
sudo apt install zsh
Verify the installation:
zsh --version
Set Zsh as the default shell:
chsh -s $(which zsh)
Restart the terminal or log out and back in for the shell change to take effect.
Install Oh My Zsh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
This installs Oh My Zsh and creates a default configuration file at ~/.zshrc. The existing Bash configuration is not affected.
Step 2: Configure Your .zshrc File
All Zsh and Oh My Zsh settings live in ~/.zshrc. Open it with any editor:
nano ~/.zshrc
The two most important settings to locate and edit are the theme and the plugin list:
ZSH_THEME="agnoster"
plugins=(git z docker node npm npx autojump zsh-autosuggestions zsh-syntax-highlighting)
After making changes, reload the configuration:
source ~/.zshrc
Step 3: Choose a Theme
Oh My Zsh ships with over 250 themes. The right choice depends on how much information you want visible in the prompt and how much visual complexity you prefer.
Commonly used options:
robbyrussell -- The default theme. Minimal and clean, shows the current directory and Git branch.
agnoster -- Adds Git status indicators and a powerline-style prompt. Requires a Nerd Font installed in the terminal.
avit / minimal -- Good for distraction-free environments where prompt information is secondary.
Powerlevel10k -- Highly configurable, fast, and visually informative. The most popular choice for developers who want a detailed prompt without performance overhead.
To install Powerlevel10k:
git clone https://github.com/romkatv/powerlevel10k.git $ZSH_CUSTOM/themes/powerlevel10k
Set it in .zshrc:
ZSH_THEME="powerlevel10k/powerlevel10k"
Reload the configuration and Powerlevel10k will run its setup wizard on the next terminal launch, walking through prompt customization interactively.
Step 4: Enable Useful Plugins
Plugins are enabled by adding their names to the plugins list in .zshrc. They are loaded when the shell starts.
The most useful plugins for developers:
Plugin | What it adds |
|---|---|
| Aliases for common Git commands and branch info in the prompt |
| Tab completion for Docker commands and flags |
| Kubernetes command completion |
| AWS CLI tab completion |
| Node.js tooling shortcuts |
| Jump to frequently visited directories by partial name |
| Suggests completions based on command history as you type |
| Highlights valid commands in green and invalid ones in red as you type |
zsh-autosuggestions and zsh-syntax-highlighting are external plugins and need to be cloned before they can be enabled:
git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
git clone https://github.com/zsh-users/zsh-syntax-highlighting ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
Then add them to the plugins list and reload:
plugins=(git docker kubectl aws npm npx autojump zsh-autosuggestions zsh-syntax-highlighting)
source ~/.zshrc
Step 5: Keyboard Shortcuts Worth Knowing
These shortcuts work in Zsh and save repeated keystrokes throughout a working session:
Shortcut | Action |
|---|---|
| Search command history interactively |
| Move cursor to beginning of line |
| Move cursor to end of line |
| Paste the last argument from the previous command |
| Autocomplete commands, paths, and flags |
| Cycle through history entries matching the current input |
With zsh-autosuggestions active, pressing the right arrow key accepts the suggested completion. This alone removes a significant amount of repetitive typing for frequently used commands.
Step 6: Aliases and Environment Variables
Aliases
Aliases define shorthand commands that expand to longer ones. Add them to .zshrc:
alias ll='ls -la'
alias g='git'
alias serve='python3 -m http.server'
Reload for changes to take effect:
source ~/.zshrc
Environment Variables
Environment variables can be set directly in .zshrc for values that should be available in interactive sessions:
export PATH="/usr/local/opt/node@18/bin:$PATH"
export EDITOR="code --wait"
For variables that should be available to all processes, including non-interactive shells, use ~/.zshenv instead:
# ~/.zshenv
export GOPATH=$HOME/go
export PATH="$GOPATH/bin:$PATH"
The distinction matters for tools launched outside the terminal, such as GUI applications or scripts triggered by system processes, which do not source .zshrc.
Key Takeaways
Zsh improves on Bash with context-aware autocompletion, shared history across sessions, and better scripting capabilities.
Oh My Zsh makes Zsh configuration manageable through a structured plugin and theme system.
Powerlevel10k is the most capable theme option and configures itself interactively on first run.
zsh-autosuggestionsandzsh-syntax-highlightingare external plugins that require cloning before they can be enabled.Aliases and environment variables in
.zshrcreduce repetitive typing and keep common paths consistent across projects..zshenvis the correct place for environment variables that need to be available to all processes, not just interactive terminal sessions.
Conclusion
A well-configured terminal is one of those investments that pays back quickly. The initial setup takes under an hour, and the daily benefits accumulate across every project and workflow that involves the command line.
The setup described here is portable. The .zshrc file can be stored in a dotfiles repository and applied to any new machine, which means the same environment is available whether you are working on a personal machine, a remote server, or a fresh development VM.
Have a plugin or alias that has made a real difference to your workflow? Share it in the comments.




