10 Powerful Fish Shell Features That Replace Your Bash Plugins

The fish shell does out of the box what bash needs a dozen plugins to do. Autosuggestions, syntax highlighting, and smart tab completions all work the moment you install it, with zero configuration. I switched my daily driver terminal to fish two years ago and the only thing I miss about bash is nothing. The project sits at over 34,000 stars on GitHub and version 4 rewrote the internals in Rust, so it is not some niche experiment. It is a mature default shell candidate for any Linux desktop or dev machine.

Here are ten features that justify the switch, plus installation steps and a few honest reasons to stay on bash for certain jobs.

1. Autosuggestions That Learn From Your History

Start typing and fish shows the rest of the command in gray text, pulled from your history and valid completions. Press the right arrow key to accept it. That is the entire feature. No plugin manager, no zsh-autosuggestions clone to install and update.

The suggestions are context aware. Type ssh and the fish shell suggests hosts you have connected to before. Type cd and it suggests directories that actually exist. After a week your most common twenty commands become two keystrokes each.

2. Syntax Highlighting Built Into the Fish Shell

Commands turn blue when they exist and red when they do not. Invalid paths get underlined before you press Enter. Quoted strings get their own color, so a missing closing quote is obvious immediately.

This catches typos before they run. I have lost count of how many rm mistakes this has prevented, because a mistyped path shows up red instead of silently matching nothing or, worse, matching something else.

3. Tab Completions Generated From Man Pages

The fish shell parses installed man pages and builds completions from them automatically. Type tar - and press Tab, and you get every flag with a one-line description next to it. This works for thousands of commands you never configured.

Bash needs the bash-completion package plus per-tool scripts to get anywhere close. Fish ships it as core behavior and refreshes the data with fish_update_completions.

4. Scripting Syntax a Human Can Read

No more if [ "$x" = "y" ]; then ... fi. The fish shell uses plain words:

if test "$status" -eq 0
    echo "worked"
else
    echo "failed"
end

Every block ends with end. Variables are set with set name value instead of the fragile name=value form where a stray space breaks everything. Word splitting does not mangle variables with spaces in them, which kills an entire category of quoting bugs.

5. Edit Functions Live With funced

Run funced myfunction and fish opens the function in your editor. Save, and the change applies to the running session instantly. Run funcsave myfunction and it persists to ~/.config/fish/functions/ as its own file.

Each function lives in a separate file that loads on demand. Your config stays organized without a 400-line rc file that you dread opening.

6. Universal Variables Sync Across Every Session

Set a variable with set -U EDITOR nvim and it applies to every open terminal immediately, plus every future one. No sourcing rc files, no closing and reopening tabs. Fish syncs universal variables across sessions on its own.

This is my favorite underrated feature. Change your color theme in one terminal and watch the other three update in real time.

7. Abbreviations Beat Aliases in the Fish Shell

Run abbr -a gc git commit and typing gc followed by space expands it to git commit right on the command line. You see the full command before running it, and your history stores the real command instead of a cryptic shortcut.

Aliases hide what they do. Abbreviations show their work, which matters when you paste history into documentation or a script.

8. Configure From the Browser with fish_config

Run fish_config and fish starts a local web server, then opens a page where you pick color themes and prompts by clicking on previews. Changes apply through universal variables, so every open session updates as you click.

Prefer the terminal? fish_config theme show lists themes inline and fish_config prompt choose switches prompts without the browser.

9. Manage PATH Without the Usual Mess

Adding a directory to PATH in bash means editing a dotfile and hoping you picked the right one. In fish it is one command: fish_add_path ~/.local/bin. It deduplicates automatically and persists. Done.

10. History Search That Actually Works

Type any part of a command and press the up arrow. The fish shell filters history to entries matching what you typed. Type docker, press up, and cycle through only your docker commands. Pair this with a dedicated history database like the one in our atuin shell history guide if you want sync across machines.

Installing the Fish Shell on Linux

The fish shell is in every major repo:

# Debian / Ubuntu
sudo apt install fish

# Fedora
sudo dnf install fish

# Arch
sudo pacman -S fish

Try it before committing by just running fish inside your current shell. To make it your login shell:

chsh -s /usr/bin/fish

Log out and back in. Your prompt, completions, and highlighting are already working. The official fish tutorial covers the syntax differences in about fifteen minutes of reading.

Tools that respect your interactive shell work fine here. Pair fish with zoxide for smarter directory jumping and fzf for fuzzy finding, both of which ship first-class fish integrations.

When Not to Use the Fish Shell

Fish is not POSIX compatible, and that is a deliberate design choice. Scripts written for bash or sh will not run in fish. This matters less than it sounds: keep #!/bin/bash shebangs on your scripts and they run under bash regardless of your interactive shell. The incompatibility only bites when you paste bash-specific one-liners with export or $( ) substitutions into an interactive fish session, and fish 4 now accepts most of those anyway.

On shared servers where every user expects bash semantics, or in minimal containers, stick with the default. For your own workstation, the fish shell removes an entire layer of configuration work that bash users carry around in dotfiles.

The fish-shell GitHub repository has the changelog and the design document explaining why the project rejects POSIX. Both are short reads and worth the context before you switch your login shell.

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Posts