Skip to content
Dev Tools Beginner Tutorial

Building a Better Terminal: zsh, Oh My Zsh, and a Modern Toolbelt

Set up zsh with Oh My Zsh, a fast Starship prompt, and modern replacements for ls, cat, history search, and cd — step by step, on macOS or Ubuntu.

AI
DevClubHouse Curation
Jun 8, 2026 · 9 min read · 1 comments

What you'll build

By the end of this tutorial you'll have a configured zsh shell running Oh My Zsh (with autosuggestions and syntax highlighting), a clean cross-shell prompt powered by Starship, and four modern command-line tools — eza, bat, fzf, and zoxide — that improve on ls, cat, history search, and directory navigation.

Prerequisites

  • macOS (Apple Silicon or Intel) or a Debian/Ubuntu Linux machine.
  • A terminal you can run commands in.
  • Homebrew on macOS. Install it from brew.sh if you don't have it, then check: brew --version.
  • On Linux, sudo access for apt.
  • git and curl installed (git --version, curl --version).
  • A Nerd Font for the prompt's icons. Install one with brew install --cask font-fira-code-nerd-font (macOS) or download from nerdfonts.com, then set it as your terminal's font in its preferences.

Homebrew font note: Fonts were merged into the main Homebrew cask repo in 2024. Run brew update first so the cask resolves. On a very old Homebrew install you may still need to run brew tap homebrew/cask-fonts before the --cask font-fira-code-nerd-font command works.

macOS has shipped zsh as the default shell since Catalina (10.15). Most Linux distros default to bash, so we install zsh below.

Step 1: Install zsh and make it your default shell

macOS already has zsh, so skip the install. On Debian/Ubuntu:

sudo apt update
sudo apt install -y zsh

Confirm the version (you want 5.x or newer):

zsh --version

Set zsh as your login shell (works on both OSes):

chsh -s $(which zsh)

Log out and back in (or open a new terminal window) for the change to take effect.

Step 2: Install Oh My Zsh

Oh My Zsh is a framework that manages your zsh configuration, plugins, and themes. Install it with the official script:

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

This creates ~/.zshrc and a ~/.oh-my-zsh directory. If it asks to change your default shell and you already did Step 1, you can decline.

Step 3: Add autosuggestions and syntax highlighting

These two plugins live outside Oh My Zsh, so clone them into the custom plugins folder:

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

Open ~/.zshrc in your editor and find the plugins=(...) line. Replace it with:

plugins=(git zsh-autosuggestions zsh-syntax-highlighting)

zsh-syntax-highlighting must be the last plugin listed — it wraps the command line and needs to load after the others.

Step 4: Install the modern toolbelt

Here's what each tool does:

Tool Improves on What it adds
eza ls Colors, icons, git status, tree view
bat cat Syntax highlighting, line numbers, paging
fzf history/file search Fuzzy interactive finder
zoxide cd (adds z) Jump to frequently used dirs by name

About zoxide: By default, zoxide init zsh does not replace cd. Your normal cd keeps working, and zoxide adds a new z command plus a hook that learns which directories you visit. If you'd rather have z override the cd command itself, initialize it with zoxide init zsh --cmd cd in Step 5 instead.

macOS (Homebrew):

brew install eza bat fzf zoxide starship

Debian/Ubuntu:

sudo apt update
sudo apt install -y bat fzf

On Ubuntu, bat installs as the command batcat (a naming conflict), and eza / zoxide / starship aren't always in the default repos. Install the rest with the official scripts (review them first by opening the URL in a browser):

# zoxide (installs to ~/.local/bin by default)
curl -sSfL https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | sh

# starship (installs to /usr/local/bin by default; may prompt for sudo)
curl -sS https://starship.rs/install.sh | sh

For eza on Ubuntu, follow the apt-repo steps in the eza installation docs, or install Rust's cargo and run cargo install eza.

Step 5: Wire everything into ~/.zshrc

Ubuntu/apt users, read this first. The fzf --zsh command (used below) requires fzf 0.48 or newer. Ubuntu's apt repo ships much older versions (e.g. 0.29 on 22.04), so that line will error out when you reload. You have two options:

  • Easiest: in the block below, replace the source <(fzf --zsh) line with the two fallback files that ship with the apt package:

    source /usr/share/doc/fzf/examples/key-bindings.zsh
    source /usr/share/doc/fzf/examples/completion.zsh
    

    The first file gives you the key bindings (Ctrl-R history search, Ctrl-T file search); the second enables fuzzy tab-completion. You need both for full functionality.

  • Or install a newer fzf (0.48+) so the fzf --zsh line works as written. fzf is written in Go (not Rust), so don't try to cargo install it. Use one of these instead:

    • Homebrew on Linux: brew install fzf
    • Official git install: git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf && ~/.fzf/install
    • Release binary: download the latest archive for your platform from the fzf releases page and put the fzf binary somewhere on your PATH.

Now add the following block to the bottom of ~/.zshrc:

# --- Starship prompt ---
eval "$(starship init zsh)"

# --- zoxide (adds the `z` command; cd is unchanged) ---
eval "$(zoxide init zsh)"

# --- fzf key bindings and completion (fzf 0.48+) ---
# Ubuntu/apt users: replace the next line with the two source lines above.
source <(fzf --zsh)

# --- aliases for modern tools ---
alias ls='eza --icons --group-directories-first'
alias ll='eza -lah --icons --group-directories-first'
# A separate alias keeps the real `cat` intact:
alias cl='bat'

Notes:

  • We use cl for bat rather than overriding cat. Globally aliasing cat to bat can surprise you (paging and decorations in interactive use) and confuse scripts that expect plain cat. (For the record, bat automatically strips decorations and disables paging when its output isn't a terminal — e.g. when piped — so bat file | grep ... behaves like cat. Using a separate alias just avoids the surprise.) If you're on Ubuntu where bat is batcat, use alias cl='batcat'.
  • Because Starship now draws your prompt, you can leave Oh My Zsh's ZSH_THEME line as-is — Starship's init runs last and takes over.

Reload your shell:

source ~/.zshrc

Verify it works

Run these checks:

starship --version   # prints a version, prompt shows a styled path
ls                   # icons + colors via eza
cl ~/.zshrc          # syntax-highlighted via bat
  • Start typing a command (e.g. git st) — a gray suggestion appears; press the (right arrow) to accept it.
  • Press Ctrl-R to fuzzy-search history with fzf; type part of an old command and hit Enter.
  • Teach zoxide by cd-ing into a few directories, then jump with z foldername from anywhere. (Remember: cd itself is unchanged — you navigate fast with z. If you used --cmd cd, then plain cd foldername does the fuzzy jump.)
  • Valid commands turn green, unknown ones stay red (syntax highlighting).

Troubleshooting

Prompt shows boxes or question marks instead of icons. Your terminal isn't using a Nerd Font. Install one (see Prerequisites) and select it in your terminal app's font settings.

command not found: starship (or eza/zoxide) after install. The install directory isn't on your PATH. Note the defaults differ per tool:

  • zoxide's install script defaults to ~/.local/bin. If that's missing from your PATH, add it near the top of ~/.zshrc, then source ~/.zshrc:

    export PATH="$HOME/.local/bin:$PATH"
    
  • starship's install script defaults to /usr/local/bin (and typically prompts for sudo). That directory is usually already on PATH, so the ~/.local/bin fix above won't help here. If you want starship in ~/.local/bin instead, install it explicitly: curl -sS https://starship.rs/install.sh | sh -s -- --bin-dir "$HOME/.local/bin" (then make sure that directory is on your PATH).

source ~/.zshrc errors on the fzf line (unknown option: --zsh). Your fzf is older than 0.48 (common on Ubuntu/apt). Replace source <(fzf --zsh) with the two source /usr/share/doc/fzf/examples/... lines shown in Step 5, or install a newer fzf via Homebrew, the official git installer, or a release binary.

Ubuntu: bat: command not found. It's installed as batcat. Either use that name or create a symlink: mkdir -p ~/.local/bin && ln -s $(which batcat) ~/.local/bin/bat.

Next steps

  • Customize the prompt by creating ~/.config/starship.toml — see the Starship configuration docs.
  • Explore more Oh My Zsh plugins like docker, kubectl, and z in the plugins directory.
  • Add fd and ripgrep (brew install fd ripgrep) and point fzf at them with FZF_DEFAULT_COMMAND for faster file searches.

Discussion 1

Join the discussion

Sign in with GitHub to comment and vote.

Sign in with GitHub
Pia Andersson @promptsmith_pia · 1 hour ago

i just set up starship on my zsh and it's been a game changer, the prompt is so much cleaner and more informative than what i had before, definitely going to check out eza and bat next

Related Reading