Install fish
# Debian / Ubuntu
sudo apt install fish
# Arch
sudo pacman -S fish
# Fedora
sudo dnf install fish
# macOS
brew install fish
# Make it the default shell for your user
chsh -s "$(which fish)"
# (Log out and back in)
Install starship
# Universal installer
curl -sS https://starship.rs/install.sh | sh
# Or via mise / cargo / package manager
mise use -g starship@latest
brew install starship
sudo pacman -S starship
sudo apt install starship # Debian 13+ has it in main
Add to fish:
# In fish: ~/.config/fish/config.fish
starship init fish | source
Open a new fish session — the new prompt appears.
What fish gives you out of the box
- Auto-suggestions — while typing, fish shows the rest of the most-recent matching command in gray. Right-arrow accepts it.
- Syntax highlighting — valid commands are green, invalid are red, paths that exist are underlined.
- Tab completions — built from parsed man pages plus per-program completion files.
git checkout <tab>shows branches;kubectl logs <tab>shows pods. - Abbreviations — like aliases, but expand inline when you press space, so you see what's actually running:
Typeabbr -a g 'git' abbr -a gst 'git status' abbr -a k 'kubectl'gthen space; the prompt showsgit. Typegstthen space; the prompt showsgit status. No more "wait, what doesgpushalias to?" - Per-directory history —
historycan be searched by directory:history --contains foo.
What fish doesn't have
fish is intentionally not POSIX. foo && bar is foo; and bar in fish; export FOO=bar is set -x FOO bar. Most everyday scripts unchanged from bash won't run in fish without translation. Two ways to handle this:
- Run bash scripts as bash. Anything with a
#!/bin/bashshebang executes in bash regardless of your interactive shell. Same goes forbash script.sh— fish is only your interactive shell. - For deployment / CI / cron scripts, write them in POSIX sh or bash; never in fish syntax. Treat fish as your interactive shell, not your scripting language.
starship config
~/.config/starship.toml — defaults are sensible. Common tweaks:
# Don't show every cwd component — only the last two
[directory]
truncation_length = 2
truncate_to_repo = false
# Per-line layout
format = """
$username\
$hostname\
$directory\
$git_branch$git_status\
$kubernetes\
$aws\
$nodejs$python$rust$golang\
$cmd_duration\
$line_break\
$character"""
# Kubernetes context indicator (off by default for safety)
[kubernetes]
disabled = false
format = '[\($cluster:$namespace\)](bold cyan) '
# Show command duration only for commands >500ms
[cmd_duration]
min_time = 500
# Better Git branch indicator
[git_branch]
symbol = " "
format = '[$symbol$branch]($style) '
# Custom user@host only when on SSH
[username]
show_always = false
format = '[$user]($style)@'
[hostname]
ssh_only = true
The full reference: starship.rs/config. The defaults are good enough; tweaking is optional.
fish abbreviations worth setting
# ~/.config/fish/conf.d/abbreviations.fish
# Git
abbr -a g git
abbr -a gst 'git status'
abbr -a gco 'git checkout'
abbr -a gcb 'git checkout -b'
abbr -a gp 'git push'
abbr -a gpf 'git push --force-with-lease'
abbr -a gl 'git log --oneline --graph --decorate'
# Kubernetes
abbr -a k kubectl
abbr -a kg 'kubectl get'
abbr -a kgp 'kubectl get pods'
abbr -a kgs 'kubectl get services'
abbr -a kgd 'kubectl get deployments'
abbr -a kdp 'kubectl describe pod'
abbr -a kl 'kubectl logs'
abbr -a klf 'kubectl logs -f'
# Modern unix
abbr -a ls eza
abbr -a ll 'eza -lah --git'
abbr -a cat 'bat -p'
Integrate with zoxide + fzf
If you've installed zoxide and fzf (from the modern Unix CLI tutorial):
# ~/.config/fish/config.fish
zoxide init fish | source
# fzf key-bindings (Ctrl-R history, Ctrl-T file picker, Alt-C cd picker)
fzf --fish | source
Now z proj jumps to your most-frecent matching directory; Ctrl-R opens fzf-powered history search.
If you're staying with zsh / bash
starship works identically there:
# bash: ~/.bashrc
eval "$(starship init bash)"
# zsh: ~/.zshrc
eval "$(starship init zsh)"
For zsh, the canonical companion config is oh-my-zsh or prezto; pick one for plugin management and theme defaults, then add starship as the prompt. zsh's auto-suggestions plugin (zsh-autosuggestions) gives the fish-style ghost text in zsh.
Why not zsh + Oh My Zsh + Powerlevel10k?
Powerlevel10k is fast and beautiful but a sizable framework with its own DSL. fish + starship gets you the same visible benefits with less moving config and a shell whose interactive ergonomics are noticeably better. For someone whose muscle memory is deeply zsh-shaped, the switch isn't necessary; for someone starting fresh, fish + starship is the smaller, faster path.
What requires a Nerd Font
The shell-prompt icons (Git branch, language symbols, lock for SSH, etc.) come from a Nerd Font — a regular font patched with developer-friendly glyphs. Install one (nerdfonts.com); set the terminal emulator's font to it. Without a Nerd Font, you see ? boxes where icons should be.
Recommended choices: JetBrains Mono Nerd Font, Hack Nerd Font, Fira Code Nerd Font (with ligatures), Berkeley Mono Nerd Font.