---
title: "How to Enable Syntax Highlighting in Zsh"
description: "Learn how to enable syntax highlighting in ZSH to improve your coding experience. Covers installation, color customization, and optional highlighters."
date: 2026-07-12
categories: ["linux"]
tags: ["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:**

- [How to Enable Command Autocomplete in ZSH](https://www.bitdoze.com/enable-command-autocomplete-in-zsh/)
- [Top 15 Oh My ZSH Plugins You Must Try](https://www.bitdoze.com/best-oh-my-zsh-plugins/)
- [Zoxide: The Smarter Way to Navigate Your Terminal](https://www.bitdoze.com/zoxide/)

## 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:

```bash
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:**

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

If you don't have Oh My Zsh yet:

```bash
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:

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

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

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

### Option C: With Homebrew (macOS)

```bash
brew install zsh-syntax-highlighting
```

Add to the **end** of your `~/.zshrc`:

```zsh
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:

```bash
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

```zsh
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
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
ZSH_HIGHLIGHT_HIGHLIGHTERS=(main brackets cursor)
```

### Bracket matching example

Enable the `brackets` highlighter and customize the colors:

```zsh
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
ZSH_HIGHLIGHT_HIGHLIGHTERS+=(root)
ZSH_HIGHLIGHT_STYLES[root]='bg=red'
```

### Pattern highlighting

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

```zsh
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:

```zsh
# 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:

```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
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:

```bash
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](/install-fish-shell-ubuntu/) includes syntax highlighting, autosuggestions, and rich completions out of the box. See the [Fish Shell vs Zsh](/fish-shell-vs-zsh/) comparison if you want to explore that option.