Fish Shell vs Bash vs Zsh - Complete Comparison 2026

An honest comparison of Fish, Bash, and Zsh covering syntax, performance, plugins, scripting, and day-to-day usability so you can pick the right shell.

Fish Shell vs Bash vs Zsh - Complete Comparison 2026

I’ve used all three of these shells for real work. Bash was my default for years because it was just there. I switched to Zsh when Oh My Zsh blew up, and I stuck with it for a long time. Then I tried Fish on a whim, and it became my daily driver. Each shell has a personality, and the “right” one depends on what you care about.

This isn’t a theoretical comparison. I’ll walk through what actually matters when you sit down and type commands every day.

Quick overview

FeatureFishBashZsh
AutosuggestionsBuilt inNo (needs plugin)Plugin (zsh-autosuggestions)
Syntax highlightingBuilt inNoPlugin (zsh-syntax-highlighting)
Tab completionsRich, out of the boxBasicGood with plugins
POSIX compliantNoYesMostly yes
Scripting syntaxIts ownPOSIX shMostly POSIX + extensions
Config file~/.config/fish/config.fish~/.bashrc~/.zshrc
Default on LinuxNoUsually yesNo (default on macOS)
Written inRust (since 4.0)CC
Web-based configYes (fish_config)NoNo
Plugin managersFisher, Oh My FishNone built inOh My Zsh, Antigen, etc.

Autosuggestions and completions

This is where Fish pulls ahead immediately. Open a fresh Fish install, start typing, and you get grayed-out suggestions from your command history. Press the right arrow to accept. No config, no plugins, nothing to set up. I wrote a full guide on Fish Shell autocomplete and suggestions that covers everything this system can do.

Bash has nothing like this out of the box. You can install ble.sh or use fzf for fuzzy history search, but it takes effort.

Zsh gets there with zsh-autosuggestions, but you have to install it yourself. I’ve written a guide on how to enable command autocomplete in Zsh if you go that route.

Fish also parses man pages to generate completions automatically. Type git and hit tab, and you get completions for subcommands, flags, and branch names without any extra configuration. Zsh can match this with the right setup (compinit plus plugins), but it takes work. Bash’s tab completion is bare-bones by comparison.

Syntax highlighting

Fish highlights your commands as you type. Valid commands are one color, invalid ones are red, strings get their own color. You can spot typos before you press enter. I have a detailed guide on Fish Shell syntax highlighting if you want to see how it works under the hood.

Zsh needs zsh-syntax-highlighting for the same behavior. I wrote about enabling syntax highlighting in Zsh if you want that.

Bash has no built-in syntax highlighting at all.

Scripting and POSIX compatibility

Here’s the trade-off. Fish has its own scripting syntax that’s intentionally not POSIX-compliant. The Fish developers made this choice to get a cleaner language, and honestly the syntax is easier to read:

# Fish - cleaner syntax
if test -f ~/.config/fish/local.fish
    source ~/.config/fish/local.fish
end

for file in *.txt
    echo $file
end

# Variables
set greeting "hello"
echo $greeting

Compare that to Bash:

# Bash - POSIX style
if [ -f ~/.bashrc_local ]; then
    source ~/.bashrc_local
fi

for file in *.txt; do
    echo "$file"
done

# Variables
greeting="hello"
echo "$greeting"

The Fish version is more readable. But here’s the catch: you can’t copy-paste Bash one-liners from Stack Overflow and expect them to work in Fish. Anything that uses && between commands, $(...) for command substitution (Fish uses (...) without the dollar sign), or Bash-specific [[ ]] tests won’t work directly.

In practice, this matters less than you’d think. Most of the time you’re running commands, not writing shell scripts. And when you do need a shell script, you can always put #!/bin/bash at the top and run it as a Bash script from within Fish. For Fish-specific custom commands, check out my guide on Fish Shell functions.

POSIX compatibility tip

You can run any Bash script from Fish. Just use bash script.sh or make the script executable with a #!/bin/bash shebang. Fish’s non-POSIX syntax only affects what you type interactively and Fish-specific scripts.

Configuration

Fish stores its config in ~/.config/fish/config.fish and supports a conf.d/ directory for modular config files. It also has a web-based configuration tool, run fish_config and a browser opens where you can change colors, view functions, and set variables. It sounds gimmicky, but it’s genuinely useful for quickly previewing color themes.

Bash uses ~/.bashrc (and sometimes ~/.bash_profile). Everything is manual editing.

Zsh uses ~/.zshrc. With Oh My Zsh installed, you get a framework that manages plugins and themes, but the config file can get long. I covered some of the best Oh My Zsh plugins if you’re on team Zsh.

Performance

Fish 4.0 was rewritten from C++ to Rust, released in February 2025. The latest version is 4.5.0 (February 2026). Startup feels instant on my machines. It’s slightly heavier than a bare Bash shell, but the difference is measured in milliseconds and you won’t notice it.

Zsh with Oh My Zsh loaded and several plugins can be noticeably slow to start, sometimes taking over a second. There are workarounds (lazy loading, lighter plugin managers like zinit), but it’s something you have to actively manage.

Plain Bash starts the fastest because it’s the most minimal. But you also get the fewest features out of the box.

For interactive use, Fish feels the snappiest because autosuggestions and completions work instantly. The “performance” that matters most for a shell is how fast it responds while you’re typing, and Fish wins here.

Plugin ecosystems

Fish has two main plugin managers:

  • Fisher - lightweight, fast, zero config. This is what most people use now. Run fisher install author/plugin and you’re done.
  • Oh My Fish - a framework similar to Oh My Zsh. It has been unmaintained for a while and the GitHub page carries a warning about that. I’d steer toward Fisher for new setups, but if you’re curious, I have a guide on installing and using Oh My Fish.

I go into much more detail on this in Best Fish Shell plugins and tools.

Zsh has the largest plugin ecosystem thanks to Oh My Zsh, which has 300+ plugins and 150+ themes. Antigen, zinit, and zplug are alternative plugin managers with different performance profiles.

Bash doesn’t have a real plugin ecosystem. There are dotfile frameworks like bash-it, but adoption is much smaller.

Learning curve

Bash: you already know it (probably). It’s everywhere, and most Linux tutorials assume you’re using it.

Zsh: almost no learning curve coming from Bash. The syntax is nearly identical, and Oh My Zsh provides a guided experience. It’s essentially Bash with extras.

Fish: there’s a small adjustment period. The syntax differences trip you up for the first day or two, especially around variable assignment (set instead of =) and command substitution. After that, the built-in features mean you actually have less to learn overall because you don’t need to configure as much.

When to use which

Pick Fish if you want a shell that works well out of the box, you don’t write POSIX shell scripts often, and you value autosuggestions and syntax highlighting without configuration. If this sounds like you, check out how to install Fish Shell on Ubuntu to get started.

Pick Zsh if you want the best of both worlds: Bash compatibility with modern features via plugins. You’re comfortable configuring things. Oh My Zsh gives you a big community and tons of themes.

Pick Bash if you write shell scripts that need to run everywhere, you work on servers where Bash is the only shell available, or you prefer maximum POSIX compatibility.

My take

I switched to Fish about a year ago and haven’t looked back. The out-of-the-box experience is just better than anything I managed to build with Zsh plugins. Autosuggestions, syntax highlighting, man page completions, and the clean scripting syntax make day-to-day work faster.

The POSIX incompatibility bothered me for about a week. I learned to use bash -c 'command' for the occasional one-liner, and I keep my automation scripts as Bash scripts. It’s a non-issue.

If you want a deeper comparison between just Fish and Zsh, I wrote a focused article on Fish Shell vs Zsh. And if you want to customize your Fish prompt, take a look at how to set up Starship with Fish Shell or my Fish Shell themes and prompts comparison covering Tide, Starship, Pure, and Hydro.