Introduction

For most Linux users, the terminal is where they actually live. Package updates, git, servers, container logs, config files — it all funnels through the shell. Which makes your choice of shell the single most-repeated piece of software you interact with. Yet most people still run whatever shipped by default: Bash.

I used Bash for years. I never hated it — it was just there. Then I switched to Zsh with Oh My Zsh on my workstation. The first week felt like someone quietly upgraded my terminal. Commands I typed from memory started appearing before I finished typing. Typos highlighted themselves in red before I hit Enter. The prompt showed me which branch I was on, what the last command cost, and where I stood.

This is not a post about hating Bash. It is a post about why interactive, everyday Linux desktops and dev machines work better with Zsh — and why Oh My Zsh makes that switch painless. And it is honest about when you should not switch.


Why Your Interactive Shell Matters

Here is the math. Every command you type is a transaction: type, check, fix, rerun. Bash gives you raw tools for that transaction. Zsh gives you a user interface for it.

The difference shows up in small ways that compound:

  1. you don't scroll through history with arrow keys anymore — you search it
  2. you don't retype what you typed yesterday — autosuggestions finish it
  3. you don't misread a command — syntax highlighting flags it
  4. you don't guess at completions — they show up, filtered

None of these are "set up your dotfiles like a neckbeard" tricks. They are defaults once you install the right plugins. The terminal is the one place where a 10-minute setup improves every command you type afterwards.


What Zsh Gives You That Bash Doesn't

Zsh is a superset of Bash's interactive behavior with better ergonomics. The headline features:

Feature Bash Zsh
Live autosuggestions no (needs ble.sh) yes, via plugin
Syntax highlighting while typing no yes, via plugin
Rich tab-completion (git, docker, kubectl) basic deep, extensible
Recursive globbing (**/*.md) via globstar opt-in built-in, natural
Configurable prompt with git info manual themes do it for you
One-based arrays / scripts semantics POSIX-ish different, careful

The pragmatic wins for daily use:

Autosuggestions. You start typing git pu and zsh quietly suggests the rest: git push origin main. Press right-arrow, done. The feature alone kills thousands of arrow-key taps a day.

Syntax highlighting. Commands colorize as you type. A valid command is green; a typo is red; a dangerous redirect stands out. Mistakes get caught before Enter, not after.

Completions. Zsh's completion system is genuinely different from Bash's. It groups, describes, and filters. git ch <Tab> doesn't dump raw options — it shows branches, sorted and searchable. Same for systemctl, docker, kubectl, and anything with a completion definition.

Recursive globbing. find . -name "*.py" becomes **/*.py. Small, but it changes how you think about paths.

The prompt. With a theme, one glance tells you the branch, dirty-file count, exit code of the last command, and how long it took. My Bash prompt was a username, a hostname, and a dollar sign. I did not notice how much context I was missing until it appeared.


Where Oh My Zsh Fits In

Zsh alone gives you the engine. Oh My Zsh, from ohmyz.sh, is the community framework that makes the engine usable — a plugin and theme ecosystem with batteries included.

Why it matters for a switcher:

  1. No dotfile archaeology. One install command and you have a sane ~/.zshrc, syntax highlighting, history config, and a decent prompt.
  2. Plugins as one-liners. Want git shortcuts? plugins=(git) and you get 100+ aliases. Want autosuggestions? Add the plugin, done. No hunting for snippets.
  3. Themes that look like the demos. agnoster, powerlevel10k, robbyrussell — one ZSH_THEME="..." line away.
  4. Huge community. Anything you want to do — a plugin exists or the docs show the pattern.

It is not the only framework (Prezto, Zim, Zinit, Antigen all exist, and several are faster), but it is the one with the lowest barrier to entry and the largest ecosystem. For a first switch, that matters more than startup microbenchmarks.


Plugins That Pay For Themselves

Start minimal. Three plugins give 80% of the daily value:

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

If you installed Oh My Zsh the standard way, the last two come from the plugin repos:

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

Then add them to the plugins=(...) line in ~/.zshrc and reload with source ~/.zshrc.

After the first week, worth adding:

  • zsh-completionsextra completion definitions for dozens of tools
  • zoxide — a smarter cd that learns where you actually go (z blog, not cd ~/Documents/blog)
  • docker / kubectl / terraform — alias + completion packs for your daily tools
  • history-substring-search — type a fragment, arrow through matching history

The rule: every plugin adds startup cost, so only keep what you use weekly. Resisting the urge to install all 200 visible plugins is a feature, not a bug.


Installing On Fedora / AlmaLinux / Rocky

Good news for the RHEL family: zsh, git, and curl all live in the default BaseOS/AppStream repos on Fedora, AlmaLinux, and Rocky — no EPEL needed for this one. Same dnf command across all three:

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

That's it — the same command works whether you're on Fedora Workstation, an AlmaLinux server, or a Rocky Linux box. The installer detects your current shell, builds ~/.zshrc, and — same as everywhere else — offers to set Zsh as your default shell before it exits.

If you're running this on a minimal server install (common on AlmaLinux/Rocky VPS images) and curl isn't already there, the command above pulls it in as part of the same install line, so you don't need a separate step.


Installing On Debian / Ubuntu

The classic path, and the one that matches most of my earlier posts on this blog:

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

The installer detects your existing shell, creates ~/.zshrc, and — if you say yes — offers to set Zsh as your default shell right away.


Setting Zsh As Your Default

If you skip the installer prompt, do it manually:

chsh -s $(which zsh)

Log out and back in. Verify with:

echo $SHELL

It should print /bin/zsh or /usr/bin/zsh. (This is also your rollback path: chsh -s /bin/bash undoes everything.)

One migration tip worth following: keep your portable setup in the right files.

  • ~/.zshenv — PATH and environment variables (runs for every zsh, interactive or not)
  • ~/.zshrc — interactive aliases, functions, plugins, theme
  • ~/.zprofile — login-time setup

Moving a Bash setup over is mostly copying export lines into ~/.zshenv and alias lines into ~/.zshrc. A full guide to the migration is at carlosroso.com, which covers the pitfalls I skipped over here.


The Honest Tradeoffs: When Bash Stays

Nuance time, because "everyone should switch" is only true for interactive machines.

Keep Bash — or /bin/sh — in these places:

  1. Servers and containers. Bash is there, always, and it starts fast. A login shell gaining 100–500 ms of plugin load matters on every SSH session. Raw zsh cold-start tends to run noticeably slower than Bash's even before any plugins are loaded, and an unoptimized Oh My Zsh setup can push interactive startup past half a second.
  2. CI pipelines and cron. Anything non-interactive, where output is consumed by machines, should stay POSIX-ish and boring. Scripts must survive on images you don't control.
  3. Anything where third-party code is policy-limited. Plugins are community code. There have been real CVEs in the Oh My Zsh plugin ecosystem, including a 2026 arbitrary-code-execution fix in the dotenv plugin. Keep plugin lists short, update them, and never source untrusted directories. The hoop.dev securing-zsh guide is a good audit checklist.

Keep your scripts portable. Zsh is not a drop-in replacement for POSIX/Bash scripting. Arrays are one-based, floating-point arithmetic differs, and sh-oriented scripts can break. The rule that keeps everyone sane: interactive shell = zsh; scripts = /bin/sh or bash with set -euo pipefail. This is why my own posts and scripts on this blog still say #!/bin/bash — that's deliberate, and it's exactly the split I'm recommending.

If you genuinely love Bash but want the features, ble.sh brings autosuggestions and highlighting into Bash, and Bash-it offers a plugin/theme bundle. They're real options. They just aren't as mature or as widely documented as the Zsh ecosystem.


Making Zsh Fast Again

The one real objection to Zsh + Oh My Zsh is startup time. It is also solvable.

  1. Use a fast prompt. Swap the default theme for Powerlevel10k (instant, fully configurable, git info included) or an external prompt like Starship (one config across zsh, bash, fish).
  2. Lazy-load heavy tools. Don't initialize nvm or language managers at startup. Defer them with a function:
load-nvm() {
  export NVM_DIR="$HOME/.nvm"
  [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
}

nvm() { load-nvm; nvm "$@"; }
  1. Cache completions. compinit -C skips the slow recompilation pass on every start.
  2. Cut plugins. Every plugin adds load. Ten rules-of-thumb plugins are faster than fifty.

Applied, these get an interactive Zsh close to Bash's startup — and for a tool you invoke hundreds of times a day, interactive responsiveness matters more than a few milliseconds either way.


Final Thought

My take, after running Zsh on desktops and dev machines: switch your interactive shell, respect your scripts.

Zsh with a minimal Oh My Zsh set changes the feel of the terminal in ways that compound daily — fewer typo round-trips, less history scrolling, more context in the prompt. The switching cost is one install command and an afternoon of tweaking a theme. The Bash skills you already have transfer; aliases and muscle memory carry over; nothing breaks overnight.

And keep Bash for servers, CI, and scripts. That split gives you the comfortable interactive shell today and the boring, dependable shell where it matters. Best of both worlds.

Start with the four plugins: git, zsh-autosuggestions, zsh-syntax-highlighting, and one good theme. A week later, the terminal feels like it belongs to you.