Skip to content

Starship: Customise Your Shell Prompt

Your shell prompt is the most-read document in your life. You glance at it hundreds of times a day, and in return it offers you your username, your hostname — which you know, it’s your laptop — and a dollar sign with all the personality of a tax return.

Starship is the fix: a single, fast, cross-shell prompt that shows you the things you actually need — current directory, git branch and status, how long that last command took — and looks respectable doing it. It’s written in Rust, which by law we are required to mention.

This guide gets you from sad default prompt to a clean, useful setup in about five minutes.

Why Starship and not the seventeen alternatives

Section titled “Why Starship and not the seventeen alternatives”
  • Fast. Quick enough that you won’t catch it working. Your prompt will never be the thing making your shell feel sluggish, unlike that oh-my-zsh setup with forty plugins you were too polite to prune.
  • Cross-shell. One config file (~/.config/starship.toml) works identically in Bash, Zsh, Fish, PowerShell and more. Hop between machines and shells all you like; the prompt follows you like a loyal, well-dressed spaniel.
  • Modular. Every chunk of information — git branch, language versions, battery level, command duration — is a “module” you can enable, disable or restyle independently.
Terminal window
brew install starship
  1. Add the init line to your shell’s config file.

    Terminal window
    echo 'eval "$(starship init bash)"' >> ~/.bashrc
  2. Reload the config (or open a new terminal window, if you enjoy ceremony):

    Terminal window
    source ~/.bashrc
  3. You should immediately see the default Starship prompt: current directory, plus git branch and status whenever you’re inside a repository.

Nearly every Starship config doing the rounds online opens the same way: a top-level format listing the six or seven modules its author happens to care about. It looks tidy. It is also a quiet act of vandalism, because format does not add to Starship’s defaults — it replaces them, and the defaults switch on some eighty modules. Your Python virtualenv, your AWS profile and region, the REBASING 2/5 marker explaining why git has started behaving oddly, the warning that you are root on a machine that isn’t yours: all gone, traded for a prompt that photographs well.

Start from the defaults and add to them instead. Create ~/.config/starship.toml:

~/.config/starship.toml
# Name the modules whose position you care about; $all sweeps up the rest.
# Anything named here is skipped by $all, so you can reorder the prompt
# without silently binning the ~80 modules Starship enables out of the box.
format = "$username$hostname$directory$git_branch$git_state$git_status$all$character"
[directory]
truncation_symbol = "…/" # default is "", so you can't tell it truncated
[git_branch]
truncation_length = 20 # default is unlimited, and ticket branches are not
[git_status]
ignore_submodules = true # the single biggest git_status speed-up
[cmd_duration]
show_notifications = true # desktop ping when the long build finally lands
min_time_to_notify = 30000
[status]
disabled = false # off by default; surfaces the exit code
[shlvl]
disabled = false # off by default; answers "why isn't exit working"

Which gets you something along these lines:

Terminal window
…/src/lib/deep on  feature/PROJ-4417-re… [?] via  v24.19.0

Those two icons — the branch marker and the Node.js hexagon — come from a Nerd Font. If your own terminal renders them as hollow rectangles instead, that is a font problem rather than a config one, and there is a fix for it further down.

The format line is the whole trick. $all expands to every module you have not already named, so listing a handful at the front buys you ordering control and costs you nothing. $git_state sits next to the branch, which is where REBASING 2/5 wants to live. $username and $hostname go first because both are conditional: they stay invisible on your own machine, and turn up when you are root or at the far end of an SSH connection — which is precisely when you want telling.

Everything below the format line changes something. That sounds like a painfully low bar until you read a few starter configs and start noticing how many of them carefully set min_time = 2000 on a module whose default is already 2000. Which is why there is nothing here about command duration: Starship already times your commands, and already keeps quiet below two seconds. The quiet hero of this prompt is a module you never had to configure.

Save the file; the prompt updates on your next command. No reload required — Starship reads the config fresh each render.

Styles in Starship are strings — bold cyan, #7aa2f7 — scattered across however many modules you have touched. Change your mind about the accent colour and you are off on a find-and-replace expedition. Palettes fix that: name your colours once, then refer to them by name.

palette = "ninja"
[palettes.ninja]
accent = "#7aa2f7"
muted = "#565f89"
[directory]
style = "bold accent"
[git_branch]
style = "muted"

Swap a single hex value and the whole prompt follows. Define as many palettes as you like and move between them by editing the one palette line — which is roughly how theming ought to work everywhere and, disappointingly, almost never does.

Starship is unusually good at explaining itself, which is just as well for a program that runs several hundred times a day and receives almost none of your attention.

  • starship timings lists every active module alongside how long it took. If your prompt has developed a stutter, this names the culprit — nine times in ten it is git_status on a repository with a five-figure file count.

  • starship explain sets out why each module is currently showing, which is the quickest route to identifying a mystery symbol.

  • Typos are caught for you. Misspell a key and the next prompt tells you so:

    [WARN] - (starship::config): Error in 'Directory' at 'not_a_real_key': Unknown key

    Worth knowing about, because the failure mode of a config nobody validates is a setting that has never once worked and never once complained.

If your fancy new prompt shows hollow rectangles where icons should be, your font lacks the glyphs. Install a Nerd Font — patched versions of popular programming fonts with the icon set baked in — and select it in your terminal’s settings. Our terminal font roundup covers which faces are worth switching to, and which of the three Nerd Font variants you actually want.

And if your terminal renders colours like it’s 1997 or stutters when redrawing, the prompt was never the problem. Have a look at our terminal emulator roundup for the current state of the art.