How to customize your shell prompt with Starship (works for any shell)
Let's walk through how to customize your shell prompt to surface the information you care about utilizing Starship.
Starship
I chose Starship because it works cross-shell and is extremely customizable, and fast.
Installation
Detailed instructions, including for different operating systems and terminals, can be found at starship.rs
As a prerequisite, you'll want to install and enable a Nerd Font in your terminal, and enable font ligatures.
To get started, install Starship utilizing the curl
or brew
command shown below:
Next, add the Starship init script to the very end of your shell's config file:
Now just start a new instance of your shell to see your starship-enabled prompt!
Configure Starship
Starship utilizes a TOML file located at ~/.config/starship.toml
for its entire configuration.
Let's create a new config file to store our customizations:
mkdir -p ~/.config && touch ~/.config/starship.toml
Since the file lives in your $HOME
directory, it's another perfect candidate to keep in-sync between multiple computers via my remote dotfiles setup.
Data Customization
Let's decide what information we want to be available in our prompt.
Referencing the above image, we can see the prompt includes:
- Current working directory
- Git branch, status, metrics, and state
- Previous command duration (if over a certain threshold)
- NodeJS version (I move between repositories very frequently)
- Current value of
git config user.email
(I switch between work projects and open-source pretty frequently and prefer to use my personal email for OSS contributions. Having it visible saves me from having to rewrite commits đ )
Let's set up our Starship prompt to display the information above by pasting the following code into the ~/.config/starship.toml
file we created above:
# Insert a blank line between shell prompts
add_newline = true
# Increase the default command timeout to 2 seconds
command_timeout = 2000
# Define the order and format of the information in our prompt
format = """\
[îļ](fg:#3B76F0)\
$directory\
${custom.directory_separator_not_git}\
${custom.directory_separator_git}\
$symbol($git_branch[î°](fg:#FCF392))\
$symbol( $git_commit$git_status$git_metrics$git_state)$fill$cmd_duration$nodejs$all\
${custom.git_config_email}
$character"""
# Fill character (empty space) between the left and right prompt
[fill]
symbol = " "
# Disable the line break between the first and second prompt lines
[line_break]
disabled = true
# Customize the format of the working directory
[directory]
truncate_to_repo = true
format = "[īąŽ $path ]($style)"
style = "fg:text bg:#3B76F0"
[git_branch]
symbol = "ī "
format = "[ $symbol$branch(:$remote_branch) ]($style)"
style = "fg:#1C3A5E bg:#FCF392"
[git_metrics]
disabled = false
[nodejs]
format = "via [$symbol($version )]($style)"
style = "yellow"
[package]
disabled = true # Enable to output the current working directory's package version
format = "[$symbol$version]($style) "
display_private = true
# Output the command duration if over 2 seconds
[cmd_duration]
min_time = 2_000
format = "[ ī $duration ]($style)"
style = "white"
# Customize the battery indicator
[battery]
format = "[$symbol $percentage]($style) "
empty_symbol = "đĒĢ"
charging_symbol = "đ"
full_symbol = 'đ'
[[battery.display]]
threshold = 10
style = 'red'
# Output the current git config email address
[custom.git_config_email]
description = "Output the current git user's configured email address."
command = "git config user.email"
format = "\n[$symbol( î $output)]($style)"
# Only when inside git repository
when = "git rev-parse --is-inside-work-tree >/dev/null 2>&1"
style = "text"
# Output a styled separator right after the directory when inside a git repository.
[custom.directory_separator_git]
description = "Output a styled separator right after the directory when inside a git repository."
command = ""
format = "[î°](fg:#3B76F0 bg:#FCF392)"
# Only when inside git repository
when = "git rev-parse --is-inside-work-tree >/dev/null 2>&1"
# Output a styled separator right after the directory when NOT inside a git repository.
[custom.directory_separator_not_git]
description = "Output a styled separator right after the directory when NOT inside a git repository."
command = ""
format = "[î°](fg:#3B76F0)"
# Only when NOT inside a git repository
when = "! git rev-parse --is-inside-work-tree > /dev/null 2>&1"
Note: Some of the unicode characters above may appear as "boxes" here on the site. Just copy them normally and they should render correctly in the prompt.
Theming
I also tend to favor dark, "pale" theme colors in my code editor and terminal (think Dracula), but there are plenty of pre-configured palettes to choose from.
Simply search the web for available Starship themes as a lot of the most popular editor themes have been ported (alternatively, you can roll your own custom palette!)
Lately I've been using Catppuccin themes everywhere, so let's go with that.
Add the following palette configuration to the ~/.config/starship.toml
file:
# Place this line directly under the `command_timeout` entry at the top of the file
palette = "catppuccin_macchiato"
# Then, this `palettes` entry can go at the bottom of the TOML file
# You may add additional palettes as desired.
[palettes.catppuccin_macchiato]
rosewater = "#f4dbd6"
flamingo = "#f0c6c6"
pink = "#f5bde6"
mauve = "#c6a0f6"
red = "#ed8796"
maroon = "#ee99a0"
peach = "#f5a97f"
yellow = "#eed49f"
green = "#a6da95"
teal = "#8bd5ca"
sky = "#91d7e3"
sapphire = "#7dc4e4"
blue = "#8aadf4"
lavender = "#b7bdf8"
text = "#cad3f5"
subtext1 = "#b8c0e0"
subtext0 = "#a5adcb"
overlay2 = "#939ab7"
overlay1 = "#8087a2"
overlay0 = "#6e738d"
surface2 = "#5b6078"
surface1 = "#494d64"
surface0 = "#363a4f"
base = "#24273a"
mantle = "#1e2030"
crust = "#181926"
You've now configured your custom prompt!
Simply initialize a new instance of your shell to view the final result, and feel free to tweak the settings to your liking.
For a list of all available options, refer to the official config documentation.
Did you create something awesome? Show off on Twitter/X and let me know @adamdehaven!