$linuxjunkies
>

Install and Configure zsh

Install zsh, set it as your default shell, and configure history, completions, zinit plugins, and a modern prompt like Starship or Powerlevel10k.

BeginnerUbuntuDebianFedoraArch9 min readUpdated June 7, 2026

Before you start

  • A Linux system with sudo or root access
  • curl installed (for zinit and Starship installers)
  • A terminal emulator that supports 256 colours
  • A Nerd Font installed and configured in your terminal if using Powerlevel10k

Zsh (Z shell) ships with most Linux distributions but rarely as the default shell. It extends POSIX sh with interactive improvements — superior tab completion, history sharing across sessions, spelling correction, and a rich plugin ecosystem. This guide gets you from a bare install to a productive, customised zsh environment without burying you in optional extras.

Install zsh

Most distros package zsh in their main repositories. Install it with your package manager:

Debian / Ubuntu

sudo apt update && sudo apt install -y zsh

Fedora / RHEL 9+ / Rocky Linux

sudo dnf install -y zsh

Arch Linux

sudo pacman -S zsh

Confirm the installed version and binary path:

zsh --version
which zsh

You should see something like zsh 5.9 (x86_64-pc-linux-gnu) and /usr/bin/zsh. The exact path matters in the next step.

Set zsh as Your Default Shell

The standard tool is chsh (change shell). It writes to /etc/passwd for your user. The shell binary must be listed in /etc/shells — the package manager entry adds it automatically.

chsh -s $(which zsh)

You will be prompted for your password. Log out and log back in (or start a new terminal session) for the change to take effect — chsh does not affect your current session.

Verify after re-login:

echo $SHELL

Expected output: /usr/bin/zsh

Note for RHEL/Rocky system users: On systems where your account is managed by LDAP or SSSD, chsh may be blocked. Ask your admin to update the directory entry, or use usermod -s /usr/bin/zsh username as root.

First Launch and the zsh New-User Wizard

On first launch zsh presents an interactive setup wizard (zsh-newuser-install). If you plan to manage ~/.zshrc manually or via a framework, press q to quit without writing a config file. The wizard is helpful for standalone setups but plugin managers overwrite most of what it generates anyway.

zshrc Basics

Zsh sources ~/.zshrc for every interactive shell. Here is a clean starting config you can build on:

cat > ~/.zshrc << 'EOF'
# History
HISTFILE=~/.zsh_history
HISTSIZE=10000
SAVEHIST=10000
setopt SHARE_HISTORY          # share history across sessions
setopt HIST_IGNORE_DUPS       # skip duplicate consecutive entries
setopt HIST_IGNORE_SPACE      # don't record lines starting with a space

# Completion
autoload -Uz compinit && compinit
zstyle ':completion:*' menu select   # arrow-key menu for completions

# Key bindings (emacs-style, standard on most terminals)
bindkey -e
bindkey '^[[A' history-search-backward  # Up arrow: search history
bindkey '^[[B' history-search-forward   # Down arrow

# Handy aliases
alias ll='ls -lah --color=auto'
alias gs='git status'
alias ..='cd ..'
EOF

Apply the config to your current session:

source ~/.zshrc

A few key options explained:

  • SHARE_HISTORY — every terminal window sees the same history in real time, not just on exit.
  • compinit — initialises the completion system. Run it after any plugin that adds completions.
  • zstyle menu select — enables the navigable completion menu you see in fish and other modern shells.

Install a Plugin Manager: zinit

zinit (formerly zplugin) is actively maintained, fast, and supports lazy-loading. It's a good default choice in 2024. Oh-My-Zsh is the most popular alternative; it is covered briefly below.

Install zinit

bash -c "$(curl -fsSL https://raw.githubusercontent.com/zdharma-continuum/zinit/HEAD/scripts/install.sh)"

The installer appends a loader block to ~/.zshrc. Reload the shell:

exec zsh

Add Plugins via zinit

Add these lines to ~/.zshrc after the zinit loader block. They cover the most impactful quality-of-life plugins:

# Syntax highlighting — must be last or near-last
zinit light zsh-users/zsh-syntax-highlighting

# Autosuggestions (fish-style, grey ghost text from history)
zinit light zsh-users/zsh-autosuggestions

# Improved completions from the community
zinit light zsh-users/zsh-completions

Reload again after editing:

exec zsh

You should now see grey history suggestions as you type, and shell keywords highlighted in colour.

Oh-My-Zsh Alternative

If you prefer a batteries-included framework with a large plugin directory, install Oh-My-Zsh instead. Do not use both zinit and Oh-My-Zsh — pick one.

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

Oh-My-Zsh replaces your ~/.zshrc with its own template. Enable plugins by editing the plugins=() array in that file — for example plugins=(git docker kubectl).

Prompt Frameworks

A good prompt shows branch names, exit codes, and virtualenv status without slowing startup. Two modern options stand out.

Starship is a single Rust binary that works across bash, zsh, fish, and others. Install it:

curl -sS https://starship.rs/install.sh | sh

Add the initialiser to the end of ~/.zshrc:

eval "$(starship init zsh)"

Starship reads ~/.config/starship.toml. A minimal config to show git info and trim long paths:

mkdir -p ~/.config
cat > ~/.config/starship.toml << 'EOF'
[directory]
truncation_length = 3

[git_branch]
symbol = " "

[git_status]
ahead = "↑${count}"
behind = "↓${count}"
EOF

Powerlevel10k (zsh-only, highly configurable)

Powerlevel10k (p10k) renders instantly via a precompiled prompt cache and ships an interactive configuration wizard. Install via zinit:

zinit ice depth=1; zinit light romkatv/powerlevel10k

Reload zsh and the wizard starts automatically. If it doesn't, run:

p10k configure

Powerlevel10k requires a Nerd Font to display icons correctly. Install one (e.g. JetBrainsMono Nerd Font) and configure your terminal emulator to use it before running the wizard.

Verification

Run through this checklist to confirm everything is working:

# Default shell is zsh
echo $SHELL

# History persists (type a command, open a new terminal, press Up)
# Completions work
git 

# Plugin syntax highlighting is active (type a valid command — it turns green)
ls

# Prompt shows git branch inside a repo
cd /tmp && git init test-repo && cd test-repo && git checkout -b main

Troubleshooting

chsh: PAM authentication failure

This happens when your system uses a restricted PAM configuration. Run sudo chsh -s /usr/bin/zsh your_username or edit /etc/passwd directly with sudo vipw.

Completions are slow or show warnings about insecure directories

Zsh refuses to load completion files writable by others. Fix permissions:

compaudit | xargs chmod go-w

zsh-syntax-highlighting not working

Syntax highlighting must be sourced after all other plugins. Check that its zinit light line appears last in your plugin block.

Starship prompt shows boxes instead of icons

Your terminal is not using a Nerd Font. Either install one or disable icons in starship.toml by setting symbol = "" in the relevant sections.

Config changes aren't taking effect

Always use exec zsh (replaces the current shell process) rather than source ~/.zshrc when you change plugin or prompt initialisation lines — sourcing a running shell twice can cause duplicate hooks.

tested on:Ubuntu 24.04Fedora 40Arch rollingDebian 12

Frequently asked questions

Can I use Oh-My-Zsh alongside zinit?
No — both manage plugins and modify your shell environment in conflicting ways. Choose one framework and stick with it.
Will changing my shell to zsh break existing bash scripts?
No. Scripts run by their interpreter line (#!/bin/bash) are unaffected. Only your interactive login shell changes.
Do I need a Nerd Font for zsh to work?
Only if you use a prompt theme like Powerlevel10k that renders icons. Starship works without one if you disable icon symbols in starship.toml.
How do I revert to bash if something goes wrong?
Run chsh -s /bin/bash, or log in as another user and correct the /etc/passwd entry. You can also boot a recovery shell which defaults to bash.
Why does zsh start slowly after adding plugins?
Plugins are loaded synchronously at startup by default. Use zinit's ice modifiers like 'lucid' and 'wait' to defer non-critical plugin loading until after the first prompt appears.

Related guides