The Modern Zsh Setup: Plugins, Starship & a Clean Prompt
Zsh ships as the default shell on modern macOS, but out of the box it's barebones — no autocomplete beyond the basics, no colour-coded command feedback, no intelligent history suggestions. With two Homebrew-managed plugins and Starship as your prompt engine, you get a terminal that suggests commands as you type, highlights syntax errors before you run them, and shows rich git/project context without weighing down every prompt render.
What we're installing:
zsh-autosuggestions— fish-style inline suggestions from your historyzsh-syntax-highlighting— real-time command colouringstarship— a blazing-fast, cross-shell prompt written in Rust
All three are maintained, well-documented, and trivially installed via Homebrew — no plugin manager like Oh My Zsh required.
1. Installing the Plugins with Homebrew
Homebrew installs these as regular formulae and puts the source files under $(brew --prefix)/share/. That path changes based on your architecture — /opt/homebrew on Apple Silicon, /usr/local on Intel — so using $(brew --prefix) in your config keeps everything portable.
brew install zsh-autosuggestions
brew install zsh-syntax-highlighting
brew install starship
After installing, Homebrew usually prints a Caveats section showing the exact source path for the plugin. Using
$(brew --prefix)in your config is safer and more portable than hardcoding that path.
2. Adding the Plugins to .zshrc
Plugin source lines must be added at the bottom of your ~/.zshrc. Order matters: zsh-syntax-highlighting must always be the last sourced plugin — it hooks into zsh's line editor at a low level, and loading it before other plugins can break things.
Open your .zshrc:
nano ~/.zshrc
# or: code ~/.zshrc / vim ~/.zshrc
Add these lines at the bottom:
# Autosuggestions: ghost-text suggestions from history
source "$(brew --prefix)/share/zsh-autosuggestions/zsh-autosuggestions.zsh"
# Syntax highlighting — MUST be sourced LAST
source "$(brew --prefix)/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh"
Important:
zsh-syntax-highlightingmust always be the last plugin sourced. If you add more plugins later, keep this one at the very end of your.zshrc.
Accepting autosuggestions
Press → (right arrow) or End to accept a full suggestion. Add these optional keybindings for a smoother experience:
# Accept the whole suggestion
bindkey '^F' autosuggest-accept
# Accept just one word of the suggestion
bindkey '^J' forward-word
Customise suggestion colour
The suggestion ghost text defaults to grey. Override it with any ANSI colour code:
# 244 = light grey (default). Try 240 (darker) or 32 (green)
ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="fg=244"
3. Setting Up Starship as Your Prompt
Starship automatically detects your current context — git branch, Node version, Python virtualenv, AWS profile, Kubernetes namespace — and shows only what's relevant. Configuration lives in a single TOML file.
Initialise Starship in .zshrc
Add this line before your plugin source lines:
# Starship prompt
eval "$(starship init zsh)"
Install a Nerd Font
Starship uses Nerd Font glyphs for its icons. Without a compatible font, you'll see placeholder boxes. Install via Homebrew Cask:
brew install --cask font-jetbrains-mono-nerd-font
Then set your terminal font to JetBrainsMono Nerd Font in your terminal's preferences.
Create a Starship config
Starship reads from ~/.config/starship.toml. Here's a clean starting config:
# ~/.config/starship.toml
# Remove blank line between prompts (see section 4)
add_newline = false
# Prompt format
format = """
$directory$git_branch$git_status$nodejs$python$rust$package
$character"""
[directory]
style = "bold cyan"
truncation_length = 3
truncate_to_repo = true
[git_branch]
symbol = " "
style = "bold purple"
[git_status]
conflicted = "⚡"
ahead = "⇡${count}"
behind = "⇣${count}"
modified = "~"
untracked = "?"
staged = "+"
[character]
success_symbol = "[❯](bold green)"
error_symbol = "[❯](bold red)"
[nodejs]
symbol = " "
style = "bold green"
[python]
symbol = " "
4. Removing the Blank Line Before Each Prompt
By default, Starship inserts an empty line above each prompt to visually separate commands. There are a few ways to remove it.
Option A — Starship config (recommended)
Set add_newline = false in ~/.config/starship.toml. This is already included in the config above.
add_newline = false
Option B — Suppress it in .zshrc
If you're not using Starship, or want to suppress zsh's own newline behaviour:
# Remove zsh's end-of-line marker (the % sign)
PROMPT_EOL_MARK=''
Option C — Combine both
For maximum compactness, set add_newline = false in starship.toml and add this to .zshrc:
PROMPT_EOL_MARK=''
The
%that sometimes appears at the end of command output is zsh's end-of-line marker. SettingPROMPT_EOL_MARK=''hides it for a cleaner look.
5. The Complete .zshrc
Here's a clean, production-ready .zshrc that brings everything together in the correct order.
# ══════════════════════════════════════════════════════════
# ~/.zshrc — Modern Zsh Configuration
# ══════════════════════════════════════════════════════════
# ── History ───────────────────────────────────────────────
HISTSIZE=10000
SAVEHIST=10000
HISTFILE=~/.zsh_history
setopt HIST_IGNORE_DUPS
setopt SHARE_HISTORY
# ── Completion ────────────────────────────────────────────
autoload -Uz compinit && compinit
zstyle ':completion:*' menu select
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'
# ── Useful aliases ────────────────────────────────────────
alias ls='ls --color=auto'
alias ll='ls -lAh'
alias grep='grep --color=auto'
# ── Suppress blank line / EOL marker ──────────────────────
PROMPT_EOL_MARK=''
# ── Starship Prompt ───────────────────────────────────────
# (add_newline = false is set in ~/.config/starship.toml)
eval "$(starship init zsh)"
# ── Autosuggestion colour ─────────────────────────────────
ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="fg=244"
# ── Optional keybindings ──────────────────────────────────
bindkey '^F' autosuggest-accept
bindkey '^J' forward-word
# ── Plugins (syntax-highlighting MUST be last) ────────────
source "$(brew --prefix)/share/zsh-autosuggestions/zsh-autosuggestions.zsh"
source "$(brew --prefix)/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh"
Apply the changes:
source ~/.zshrc
6. Tips & Common Issues
Verify Homebrew prefix
If sourcing the plugins fails, confirm where Homebrew installed them:
brew --prefix
# Apple Silicon → /opt/homebrew
# Intel Mac → /usr/local
# Find the plugin file directly
ls "$(brew --prefix)/share/zsh-autosuggestions/"
Starship icons appear as boxes
Your terminal font isn't set to a Nerd Font. In iTerm2: Preferences → Profiles → Text → Font. In Terminal.app: Preferences → Profiles → Text → Change Font. Select any Nerd Font variant.
Explore Starship presets
Starship ships with a library of community presets:
# List available presets
starship preset --list
# Apply one (e.g. Tokyo Night)
starship preset tokyo-night -o ~/.config/starship.toml
# Revert to a blank config
starship preset blank -o ~/.config/starship.toml
Check plugin load time
If your shell feels slow, profile startup time:
time zsh -i -c exit
Starship is extremely fast — typically under 5ms per prompt render. If your shell is slow, the culprit is almost always compinit running without a cache check. Replace compinit with compinit -C to skip the security check on subsequent loads (safe for personal machines).