Bitdoze Logo

How to Enable Syntax Highlighting in Zsh

Learn how to enable syntax highlighting in ZSH to improve your coding experience. Covers installation, color customization, and optional highlighters.

DragosDragos14 min read
How to Enable Syntax Highlighting in Zsh

Zsh doesn’t colorize commands as you type by default. The zsh-syntax-highlighting plugin fixes that. It highlights commands, options, strings, paths, and errors in real time, similar to how Fish shell works out of the box.

With syntax highlighting, valid commands show up in one color, invalid commands in another, strings and paths get their own colors too. You catch typos before pressing Enter.

ZSH comes pre-installed on macOS (since Catalina). On Linux, you’ll need to install it first.

Related ZSH guides:

What zsh-syntax-highlighting does

The plugin highlights your command line as you type, before you press Enter. It colorizes:

  • Commands: valid commands in one color, unknown/invalid commands in red (by default)
  • Options: flags like --verbose or -la get distinct colors
  • Strings: single-quoted, double-quoted, and unquoted strings are differentiated
  • Paths: existing file paths are highlighted (underlined by default)
  • Reserved words: if, for, while, case, etc.
  • Globs and expansions: *.txt, $(command), $variable

The default highlighter (called main) covers these. There are also optional highlighters for bracket matching, regex patterns, and root-user warnings (more on those below).

The plugin requires ZSH 4.3.11+. Every modern ZSH version meets this.

Step 1: Install zsh-syntax-highlighting

There are four ways to install it. Pick the one that fits your setup.

Option A: With Oh My Zsh

If you’re using Oh My Zsh:

git clone https://github.com/zsh-users/zsh-syntax-highlighting.git \
  ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting

Then edit ~/.zshrc and add zsh-syntax-highlighting to your plugins list. It must be the last plugin in the list:

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

If you don’t have Oh My Zsh yet:

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

Option B: Manual install (without Oh My Zsh)

Clone the repo and source the script:

git clone https://github.com/zsh-users/zsh-syntax-highlighting.git \
  ~/.zsh/zsh-syntax-highlighting

Add this to the end of your ~/.zshrc:

source ~/.zsh/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh

Option C: With Homebrew (macOS)

brew install zsh-syntax-highlighting

Add to the end of your ~/.zshrc:

source $(brew --prefix)/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh

Option D: System package manager (Linux)

The plugin is packaged for most Linux distributions:

Distro Package name Source command
Debian/Ubuntu zsh-syntax-highlighting source /usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
Fedora zsh-syntax-highlighting source /usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
Arch Linux zsh-syntax-highlighting (AUR/community) source /usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
openSUSE zsh-syntax-highlighting source /usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh

Install with your package manager, then add the appropriate source line to the end of your ~/.zshrc.

Step 2: Source it at the end of .zshrc

This is the most common mistake people make. zsh-syntax-highlighting must be sourced after everything else in your .zshrc, after Oh My Zsh, after compinit, after other plugins, after custom widgets.

The plugin works by hooking into ZSH’s line editor (ZLE). If it’s sourced before other things that modify the command line, those modifications won’t trigger re-highlighting.

If you’re using Oh My Zsh and zsh-syntax-highlighting is the last plugin in your plugins=() array, this is handled automatically. For manual installs, put the source line at the very bottom of .zshrc.

Step 3: Reload and test

Apply the changes:

source ~/.zshrc

Or open a new terminal tab. Then test:

  1. Type a valid command like ls. It should appear colored (green by default in many themes).
  2. Type a nonexistent command like asdfg. It should appear in red.
  3. Type echo "hello". The string "hello" should have its own color.

If you see colors, it’s working.

Customizing syntax highlighting colors

The default colors are reasonable, but you can override any of them. Add these to ~/.zshrc before the source line for the plugin.

Common style overrides

typeset -A ZSH_HIGHLIGHT_STYLES

# Valid commands, default is 'fg=green' on many setups
ZSH_HIGHLIGHT_STYLES[command]='fg=blue,bold'

# Unknown commands, default is 'fg=red'
ZSH_HIGHLIGHT_STYLES[unknown-token]='fg=red,bold'

# Aliases
ZSH_HIGHLIGHT_STYLES[alias]='fg=magenta,bold'

# Shell builtins (cd, echo, export, etc.)
ZSH_HIGHLIGHT_STYLES[builtin]='fg=blue'

# Shell reserved words (if, for, while, case)
ZSH_HIGHLIGHT_STYLES[reserved-word]='fg=yellow,bold'

# Existing file paths
ZSH_HIGHLIGHT_STYLES[path]='fg=cyan,underline'

# Strings in single quotes
ZSH_HIGHLIGHT_STYLES[single-quoted-argument]='fg=yellow'

# Strings in double quotes
ZSH_HIGHLIGHT_STYLES[double-quoted-argument]='fg=yellow'

# Command options/flags (--verbose, -la)
ZSH_HIGHLIGHT_STYLES[single-hyphen-option]='fg=cyan'
ZSH_HIGHLIGHT_STYLES[double-hyphen-option]='fg=cyan'

# Globbing expressions (*.txt, *.log)
ZSH_HIGHLIGHT_STYLES[globbing]='fg=green,bold'

# Redirection operators (>, >>, |)
ZSH_HIGHLIGHT_STYLES[redirection]='fg=magenta'

# Command substitutions ($(echo foo))
ZSH_HIGHLIGHT_STYLES[command-substitution]='fg=cyan'

# Assignments (FOO=bar)
ZSH_HIGHLIGHT_STYLES[assign]='fg=green'

Disable a specific highlight

To turn off highlighting for a particular style:

ZSH_HIGHLIGHT_STYLES[globbing]='none'

Available style names

The main highlighter defines these style keys (this is not exhaustive, but covers the ones you’d most likely want to customize):

Style name What it highlights
command External command names
alias Aliases
builtin Shell builtins (cd, pwd, shift)
function Function names
reserved-word if, for, while, case, etc.
unknown-token Invalid/unknown commands (errors)
path Existing file paths
path_prefix Prefixes of existing paths
single-quoted-argument 'single quoted' strings
double-quoted-argument "double quoted" strings
dollar-quoted-argument $'dollar quoted' strings
single-hyphen-option -o style flags
double-hyphen-option --option style flags
globbing Glob patterns (*.txt)
redirection <, >, >>, pipes
comment Comments (when INTERACTIVE_COMMENTS is set)
assign Variable assignments
default Everything else

The color syntax follows ZSH’s zle_highlight format: fg=color,bold, bg=color, underline, standout, etc. You can combine attributes with commas.

Optional highlighters

The main highlighter is active by default. The plugin ships with several others you can enable:

Highlighter What it does
main Command, option, string, path highlighting (default)
brackets Matches brackets and parentheses with colors
pattern Highlights text matching user-defined patterns
regexp Highlights text matching user-defined regexps
cursor Highlights the cursor position
root Highlights the entire line when running as root (red background)
line Applies a style to the entire command line

To enable additional highlighters, add them to the ZSH_HIGHLIGHT_HIGHLIGHTERS array:

ZSH_HIGHLIGHT_HIGHLIGHTERS=(main brackets cursor)

Bracket matching example

Enable the brackets highlighter and customize the colors:

ZSH_HIGHLIGHT_HIGHLIGHTERS+=(brackets)

# Matched bracket pair
ZSH_HIGHLIGHT_STYLES[bracket-level-1]='fg=cyan,bold'
ZSH_HIGHLIGHT_STYLES[bracket-level-2]='fg=green,bold'
ZSH_HIGHLIGHT_STYLES[bracket-level-3]='fg=magenta,bold'

# Unmatched bracket (error)
ZSH_HIGHLIGHT_STYLES[cursor-matchingbracket]='standout'

Root user warning

The root highlighter makes the entire command line visually distinct when you’re logged in as root. A good safety net:

ZSH_HIGHLIGHT_HIGHLIGHTERS+=(root)
ZSH_HIGHLIGHT_STYLES[root]='bg=red'

Pattern highlighting

Highlight specific patterns you define. Useful for flagging risky commands:

ZSH_HIGHLIGHT_HIGHLIGHTERS+=(pattern)
ZSH_HIGHLIGHT_PATTERNS+=('rm -rf *' 'fg=white,bold,bg=red')

This makes rm -rf commands stand out with a red background.

Putting it all together

A minimal ~/.zshrc with syntax highlighting configured:

# Oh My Zsh
export ZSH="$HOME/.oh-my-zsh"
plugins=(git zsh-autosuggestions zsh-syntax-highlighting)
source $ZSH/oh-my-zsh.sh

# Completion styles
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}'
zstyle ':completion:*' menu select

# Syntax highlighting customization (before the plugin sources)
ZSH_HIGHLIGHT_STYLES[unknown-token]='fg=red,bold'
ZSH_HIGHLIGHT_STYLES[command]='fg=blue,bold'
ZSH_HIGHLIGHT_STYLES[alias]='fg=magenta,bold'

Without Oh My Zsh:

# Completion system
autoload -Uz compinit && compinit

# Plugins
source ~/.zsh/zsh-autosuggestions/zsh-autosuggestions.zsh

# Syntax highlighting, must be LAST
ZSH_HIGHLIGHT_STYLES[unknown-token]='fg=red,bold'
ZSH_HIGHLIGHT_STYLES[command]='fg=blue,bold'
source ~/.zsh/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh

Note: with manual installs, the ZSH_HIGHLIGHT_STYLES overrides go before the source line.

Limiting highlight length

If you edit very long command lines and notice lag, you can limit the maximum line length that gets highlighted:

ZSH_HIGHLIGHT_MAXLENGTH=512

Lines longer than 512 characters won’t be highlighted. The default is no limit.

Troubleshooting

No colors appearing: Make sure the source line is at the very end of .zshrc. This is the single most common fix. Run source ~/.zshrc or open a new terminal to test.

Plugin not found (Oh My Zsh): Verify the plugin directory exists:

ls ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting

If it’s empty, re-clone the plugin.

Colors look wrong or invisible: Your terminal color scheme might conflict. For example, if your background is dark green and “valid command” is also green, you won’t see anything. Adjust the styles as shown in the customization section, or change your terminal’s color scheme.

Highlighting breaks after adding other plugins: Since zsh-syntax-highlighting must be sourced last, adding a new plugin after it can cause issues. In Oh My Zsh, make sure zsh-syntax-highlighting stays at the end of your plugins=() array. For manual installs, move its source line to the bottom.

Slow typing on long commands: Set ZSH_HIGHLIGHT_MAXLENGTH to a reasonable value (like 512) to skip highlighting on very long inputs.

Want syntax highlighting without plugins? Fish Shell includes syntax highlighting, autosuggestions, and rich completions out of the box. See the Fish Shell vs Zsh comparison if you want to explore that option.