Try

Or browse

    macOS

    My Starship Prompt Setup

    My Starship Prompt Setup

    My full Gruvbox Starship config, plus how to try the built-in presets and swap in Tokyo Night, Nord or Dracula colours without rewriting your starship.toml.

    Suggest editsRSSFollow on Google

    I spend alot of time in the terminal on both my home and work machines so have taken the time to get my terminal prompt looking good and I had been using PowerLine10k↗ for a few years.

    After trying to debug why my terminal was opening slowly I spotted the warning below at the top of the projects repo:

    I decided it was time for a change.

    Why Starship?

    After some quick Googling I decided upon Starship↗, it is a cross-shell prompt written in Rust that’s fast, customizable, and incredibly feature-rich. Its repo boasts that unlike traditional shell prompts, Starship:

    • Works across multiple shells (zsh, bash, fish, PowerShell)
    • Is blazingly fast (written in Rust)
    • Provides context-aware information
    • Supports extensive customization through a simple TOML file
    • Has minimal dependencies

    That ticks a lot of boxes so I decided to give it a try.

    The Design Philosophy

    My prompt design follows a few key principles:

    1. Information density without clutter: Show relevant context without overwhelming
    2. Visual hierarchy: Use color and positioning to prioritize information
    3. Gruvbox aesthetics: Maintain a consistent retro-groove color scheme
    4. Left-to-right narrative: Left side shows “where I am,” right side shows “what’s happening”
    5. Look good: I take a lot of screen shots and do screen shares - so it needs to look good !!!

    Now this is a little zoomed in, but this is what my prompt looks like:

    Prompt Layout

    The Color Palette: Gruvbox Dark

    I’m using the Gruvbox↗ Dark color scheme, which provides a warm, retro aesthetic that’s easy on the eyes during long coding sessions. The palette includes:

    • Orange (#d65d0e): System and user context
    • Yellow (#d79921): Current directory and status
    • Aqua (#689d6a): Git information
    • Blue (#458588): Programming language indicators
    • Purple (#b16286): Time display
    • Red (#cc241d): Battery and critical indicators

    The Prompt Layout

    My prompt is divided into segments, connected with powerline-style arrows. Here’s the breakdown:

    Left Side: Contextual Information

    OS and Username Segment (Orange)
    [os]
    disabled = false
    style = "bg:color_orange fg:color_fg0"
    [username]
    show_always = true
    format = '[ $user ]($style)'

    The prompt starts with the OS icon (on macOS) and username. While some people hide the username, I keep it visible-it’s a quick visual confirmation of which system I’m on, especially when dealing with remote sessions.

    Directory Segment (Yellow)
    [directory]
    format = "[ $path ]($style)"
    truncation_length = 3
    truncation_symbol = " "
    truncate_to_repo = true

    The current directory is shown with intelligent truncation. If I’m in a git repository, it truncates relative to the repo root. I’ve also added custom substitutions with icons for common directories, such as ~/Code/, ~/Documents and ~/Downloads:

    CodeDocumentsDownloadsPictures
    Git Metrics Segment (Aqua)
    [git_metrics]
    disabled = false
    format = '[[+$added]($added_style)/[-$deleted]($deleted_style) ]'

    This is where things get interesting. The git segment shows four pieces of information:

    1. Branch name with an icon
    2. Git status showing staged/modified/untracked files
    3. Git state for operations like rebasing or merging
    4. Git metrics showing additions and deletions
    Git Metrics

    The metrics feature is particularly useful-at a glance, I can see +7/-7 to understand the scope of my changes.

    Language Environment Segment (Blue)

    This segment automatically detects and displays icons for active programming environments:

    PythonNode.jsGo

    The segment only appears when relevant files are detected in the current directory, keeping the prompt clean when you’re not in a project.

    Right Side: Status Information

    Using the $fill variable, I push status information to the right side of the terminal:

    Time (Purple)

    [time]
    disabled = false
    time_format = "%R"
    format = '[[ 󰥔 $time ]]'

    A simple 24-hour clock (e.g., 14:30). Some find this redundant, but I appreciate having timestamps in my terminal sessions.

    Battery (Red background)

    [battery]
    full_symbol = "󰁹"
    charging_symbol = "󰂄"
    discharging_symbol = "󰂃"

    Battery status with appropriate icons. The red background serves as a visual alert when I’m unplugged.

    Command Duration (Aqua)

    [cmd_duration]
    min_time = 2000
    format = '[[ $duration ]]'

    Shows execution time for commands that take longer than 2 seconds. This is invaluable for understanding which operations are slow and need optimization.

    Exit Status (Yellow)

    Displays an error indicator (✖) when the last command failed, along with the exit code.

    Background Jobs (Orange)

    Shows a icon with a count when there are background jobs running.

    The Command Line

    Finally, after all the context, comes the actual command line:

    [character]
    success_symbol = '[](bold fg:color_bright_green)'
    error_symbol = '[](bold fg:color_bright_red)'

    A simple ❯ that turns red when the previous command failed. I’ve also configured vim mode indicators (since I use vi-mode in zsh):

    • Normal mode (green)
    • Replace mode (purple)
    • Visual mode (yellow)

    Performance Considerations

    Starship is fast, but I’ve made a few tweaks to ensure it stays that way:

    scan_timeout = 35
    command_timeout = 700

    The scan_timeout controls how long Starship spends looking for context (like git repos), while command_timeout limits how long individual modules can run. These values ensure the prompt never feels laggy.

    Installation

    Want to use this configuration? Here’s how:

    1. Install Starship:

      Terminal window
      brew install starship
    2. Install a Nerd Font: The icons require a Nerd Font. I use Hack Nerd Font Mono:

      Terminal window
      brew install --cask font-hack-nerd-font
    3. Configure your shell: Add to your ~/.zshrc:

      Terminal window
      eval "$(starship init zsh)"
    4. Edit your configuration: Find the configuration at ~/.config/starship.toml

    Themes and presets

    If you’ve landed here looking for a theme rather than my exact setup, there are two ways to go about it: start from one of the presets that ship with Starship, or keep a layout you like and swap the colours underneath it.

    Starting from a built-in preset

    Presets are complete starship.toml files that Starship ships with, and they make a good starting point if you don’t fancy building a prompt from scratch. To see which ones your version knows about, run:

    List the built-in presets
    starship preset --list

    On Starship 1.26.0 that gives you twelve:

    • tokyo-night, gruvbox-rainbow, catppuccin-powerline and pastel-powerline are full powerline-style themes, and the closest to what I’m running
    • pure-preset copies the look of the Pure zsh prompt, and jetpack is a minimal take inspired by the geometry and spaceship prompts
    • bracketed-segments wraps each module in brackets instead of using the default “via” and “on” wording
    • nerd-font-symbols, no-nerd-font and plain-text-symbols only change the icons, which is handy on a machine without a Nerd Font installed
    • no-runtime-versions and no-empty-icons trim things back by hiding language versions and icons for tools that aren’t installed

    A preset replaces your whole config rather than merging with it, so back up what you have first:

    Back up your config and apply a preset
    cp ~/.config/starship.toml ~/.config/starship.toml.bak
    starship preset tokyo-night -o ~/.config/starship.toml --force

    Without --force, the -o flag refuses to overwrite an existing file, which is a nice bit of protection. Leave off -o altogether and the preset is printed to the terminal instead, which is useful if you only want to borrow a section or two. The Starship site has a screenshot of each one:

    Swapping the colours on an existing layout

    The modules in my config don’t hard-code any hex values. Every style refers to a named colour like color_orange or color_fg0, and those names are defined once in a palette table:

    Selecting the palette
    palette = 'gruvbox_dark'
    [palettes.gruvbox_dark]
    color_fg0 = '#fbf1c7'
    color_orange = '#d65d0e'
    # ... and the rest of the colours

    That means changing theme is a case of adding a second palette table with the same names and pointing palette at it. Below are palettes for Tokyo Night, Nord and Dracula, built from each scheme’s published colours and covering the names the main blocks use.

    Gruvbox’s neutral colours are dark enough to carry the cream text the rest of my config uses. These three are much brighter, and cream text on them drops to between 1.0:1 and 3.5:1 contrast, so in each one color_fg0 flips to the theme’s background colour. Dark text clears 4.4:1 on every block apart from Nord’s red, which manages 3.1:1.

    Tokyo Night
    palette = 'tokyo_night'
    [palettes.tokyo_night]
    color_fg0 = '#1a1b26'
    color_fg1 = '#c0caf5'
    color_bg0 = '#1a1b26'
    color_bg1 = '#292e42'
    color_bg3 = '#414868'
    color_blue = '#7aa2f7'
    color_aqua = '#7dcfff'
    color_green = '#9ece6a'
    color_orange = '#ff9e64'
    color_purple = '#bb9af7'
    color_red = '#f7768e'
    color_yellow = '#e0af68'
    color_bright_green = '#9ece6a'
    color_bright_red = '#f7768e'
    Nord
    palette = 'nord'
    [palettes.nord]
    color_fg0 = '#2e3440'
    color_fg1 = '#eceff4'
    color_bg0 = '#2e3440'
    color_bg1 = '#3b4252'
    color_bg3 = '#4c566a'
    color_blue = '#81a1c1'
    color_aqua = '#88c0d0'
    color_green = '#a3be8c'
    color_orange = '#d08770'
    color_purple = '#b48ead'
    color_red = '#bf616a'
    color_yellow = '#ebcb8b'
    color_bright_green = '#a3be8c'
    color_bright_red = '#bf616a'

    Dracula doesn’t have a blue as such, so its purple stands in for blue and its pink takes the purple slot:

    Dracula
    palette = 'dracula'
    [palettes.dracula]
    color_fg0 = '#282a36'
    color_fg1 = '#f8f8f2'
    color_bg0 = '#282a36'
    color_bg1 = '#44475a'
    color_bg3 = '#6272a4'
    color_blue = '#bd93f9'
    color_aqua = '#8be9fd'
    color_green = '#50fa7b'
    color_orange = '#ffb86c'
    color_purple = '#ff79c6'
    color_red = '#ff5555'
    color_yellow = '#f1fa8c'
    color_bright_green = '#50fa7b'
    color_bright_red = '#ff5555'

    Customization Tips

    The beauty of Starship is how easy it is to customize. Here are some ideas:

    • Minimize for remote sessions: Use different configs based on $SSH_CONNECTION
    • Add custom modules: Starship supports custom commands and environment variables
    • Theme variations: Swap the palette, as covered in Themes and presets above
    • Context-aware layouts: Use different formats for different directories

    Summary

    Your terminal prompt is personal - it should reflect how you work and what information you need at a glance. My Starship configuration has evolved from when I was using PowerLine10k and will continue to be added to as time goes on.

    The key is to start with something functional, then iterate. Pay attention to which information you actually use and which just becomes noise. A great prompt should feel invisible when you don’t need it and invaluable when you do.

    Since writing this, most of the changes have gone into making blocks appear only when they’re needed without leaving a stray powerline arrow behind. I’ve written that up separately in My Starship Prompt Revisited: Making Blocks Vanish Cleanly.

    You can find my current and full starship.toml configuration at the following link:

    Share

    Related terms: Command-Line InterfaceCondaDotfilesHosts FileOllamaPodman

    Comments