32blogby Studio Mitsu

Starshipプロンプト導入とstarship.toml実践

Starshipは高速なRust製プロンプト。bash/zsh/fishへの導入からstarship.tomlカスタマイズまで実践的に解説する。

by omitsu27 min read
目次

Starship は単一の Rust バイナリで bash・zsh・fish・PowerShell・Nushell・Cmd のすべてのプロンプトを置き換え、~/.config/starship.toml という1つの TOML ファイルだけで動作する。git ブランチ・言語ランタイムのバージョン・kubernetes コンテキスト・コマンド実行時間といった文脈情報を、サブシェルを起動せずに表示するため、巨大な monorepo でも常に1〜10ms で描画が終わる。インストールは curl 1行 + シェル設定ファイルに eval を1行追加するだけ。あとは starship.toml だけがプロンプト設定の唯一の置き場所になる。マシンが変わってもシェルが変わってもプロジェクトが変わっても、設定はそのまま使える。

「2018年に頑張って bash の PS1 を書いた。dotfiles リポジトリにコピーして使い回してきたけど、半分は zsh で正しく描画されないし、git status を表示するブロックは1コマンドあたり 400ms もかかるし、新しい MacBook では色がおかしい」——プロンプトでこんな経験をしたエンジニアは多いだろう。同僚のターミナルに AWS アカウント名と kubernetes namespace と Python venv が1行で並んでいるのを見て、夜中に「bash プロンプト おしゃれ」で検索してここに来た人もいるはず。

Starship はそんな状況に対する事実上の標準解だ。Rust 製の単一バイナリで、1回の描画が数 ms で終わり、すべての主要シェルを1つの設定でサポートし、100 以上のコンテキスト依存モジュールを最初から備え、設定はすべて ~/.config/starship.toml に集約される。本記事ではインストール、デフォルトモジュールの読み解き方、starship.toml の段階的なカスタマイズ、Gruvbox Rainbow や Tokyo Night などのプリセット適用、カスタムモジュールの書き方までを順に解説する。読み終わる頃には、どのマシンでも使い回せるプロンプト設定が1ファイルで完成しているはずだ。

なぜ素のbashやpowerlevel10kではなくstarshipなのか

bash の PS1、oh-my-zsh のテーマ、zsh の powerlevel10k、それぞれ存在理由がある。Starship に乗り換える具体的な理由を4つに絞って整理しておく。

  1. 1つの設定ファイルがすべてのシェルで動く~/.config/starship.toml 1ファイルで bash・zsh・fish・PowerShell・Cmd・Nushell・Xonsh・Ion・Elvish のすべてに対応する。シェルを乗り換えても、チームメンバーが違うシェルを使っていても、プロンプトはそのまま追従する。書き直し不要。
  2. 「速く見える」ではなく実際に速い。powerlevel10k は「instant prompt」というテクニック(古いプロンプトを先に表示しつつ裏で本物を計算する)で速さを稼いでいる。Starship はそんなトリックが要らないほど素で速い。1回の描画は 1〜10ms で終わる。理由は明快で、すべてのモジュールが Rust 実装で、1つのバイナリの中で並列に走り、サブシェルを fork しないからだ。
  3. 100以上のコンテキスト対応モジュール。git・40種類超の言語ランタイム(Node.js / Python / Rust / Go / Java / Kotlin / Ruby / PHP / Dart / Deno / Bun / Zig / Nim / OCaml / Crystal / Elixir / Erlang / Haskell / Lua / Perl / Scala / Swift / Typst ほか)・クラウド(AWS / Azure / GCP / OpenStack)・DevOps(Docker context / Kubernetes context / Helm / Terraform / Pulumi)・システム情報(バッテリー / 時刻 / OS / hostname)まで全部入りで、カレントディレクトリのファイルから自動的にアクティベートされる。手動 ON/OFF は要らない。
  4. デフォルトがすでに使えるstarship init を1回流すだけで、ディレクトリ・git ブランチ・git ステータス・ランタイムバージョン・コマンド実行時間・色付きシェブロンプロンプトが揃った状態になる。新しいマシンでも 30 秒で実用的なプロンプトが手に入る。

実装言語は Ruststarship/starship)。シリーズ前回の gh CLI は Go だったが、プロンプトに関しては Rust が正解だ。プロンプトはシェルコマンドを打つたびに毎回走るので、GC ポーズや fork の重さや起動オーバーヘッドが積み重なるとすぐ体感できる遅さになる。Starship は .git/HEAD を読み、package.json をパースし、kubernetes コンテキストを確認し、それでも数 ms で描画を終わらせる必要がある——これを並列実行で実現できる Rust の強みがフルに活きる場所だ。

Starshipのインストールとシェル連携

手順は2つだけ。バイナリを入れて、シェル設定ファイルに1行追加する。公式のインストールガイドに全プラットフォームが載っているが、まとめると以下の通り。

powershell
# winget(Windows 11標準)
winget install --id Starship.Starship

# Scoop
scoop install starship

# Chocolatey
choco install starship

インストール後、バージョンを確認する。

bash
starship --version
# starship 1.24.2

次にシェル設定ファイルに1行追加する。普段使うシェルのスニペットを rc ファイルに append するだけ。

bash
# ~/.bashrc
eval "$(starship init bash)"

# ~/.zshrc
eval "$(starship init zsh)"

# ~/.config/fish/config.fish
starship init fish | source

# PowerShell ($PROFILE)
Invoke-Expression (&starship init powershell)

# Nushell ~/.config/nushell/config.nu
mkdir ~/.cache/starship
starship init nu | save -f ~/.cache/starship/init.nu

新しいシェルを開くともうプロンプトは差し替わっている。starship.toml はまだ存在しないが、それでいい。デフォルトが十分使えるので、多くのユーザーは設定ファイルを触らずに何週間も過ごす。

デフォルトモジュールの中身を理解する

新しいディレクトリで初期 Starship を立ち上げるとプロンプトは大体こうなる。

text
~/projects/32blog on  master [!?] via  v22.13.0
❯

各セグメントは「コンテキストに応じて自動でアクティベートされるモジュール」で、データが空のモジュールは黙って消える設計だ。意図的にミニマルになっている。それぞれの意味と元になったモジュールを順に整理する。

セグメントモジュール表示条件内容
~/projects/32blogdirectory常時カレントディレクトリ。デフォルトで3階層に切り詰め、リポジトリのルートをシアンで強調
on mastergit_branchgit リポジトリ内ブランチ名と Nerd Font のブランチアイコン
[!?]git_status作業ツリーに変更ありstaged (+) / modified (!) / untracked (?) / conflicted (=) / ahead-behind (⇡⇣) / stashed ($)
via v22.13.0nodejs(と他25個)package.json.nvmrc を検出検出したランタイムとバージョン
character常時直前のコマンドが成功なら緑、非0終了なら赤

デフォルトの format 文字列は特殊変数 $all で、Starship の 100 個超あるモジュールが既定の順序で展開される。中身を全部見たければ次のコマンドを叩く。

bash
starship print-config --default

ビルトインのデフォルト TOML がそのまま標準出力に出る。気に入った部分を ~/.config/starship.toml にコピーして書き換えていく——これがカスタマイズの正攻法だ。

よくある誤解は「全モジュールが毎回走るのでは?」というもの。実際には違う。各モジュールには「自分が動くべきか?」を判定する関数があり、それを並列に走らせている。nodejs モジュールは package.json / .node-version / .nvmrc / *.js を探す。python モジュールは requirements.txt / pyproject.toml / Pipfile / *.py を探す。kubernetes モジュールに至ってはデフォルトで disabled = true なので、明示的に有効化しない限り走らない。これがプロンプトを高速に保っている理由で、ほとんどのモジュールは何も出力せずマイクロ秒で終わる。

starship.tomlの基本: format文字列・モジュール・パレット

編集対象は ~/.config/starship.toml の1ファイルだけ。最小構成はこれくらいでいい。

toml
# ~/.config/starship.toml
"$schema" = 'https://starship.rs/config-schema.json'

# プロンプトの前に空行を入れる
add_newline = true

# 各モジュールのタイムアウト(ミリ秒)
command_timeout = 500

# プロンプト記号をステータスで切り替える
[character]
success_symbol = '[➜](bold green)'
error_symbol   = '[✗](bold red)'

# 2秒以上かかったコマンドだけ実行時間を表示
[cmd_duration]
min_time = 2_000
format = 'took [$duration]($style) '
style = 'bold yellow'

保存して新しいシェルを開くと反映される。Starship はファイルを毎プロンプト描画ごとに読み直すので、デーモン再起動も source も不要。

format文字列の仕組み

トップレベルの format オプションが「どのモジュールがどの順番でレンダリングされるか」を決める。デフォルトは魔法の変数 $all。レイアウトを自分で決めたければ独自の format 文字列を書き、$モジュール名 でモジュールを参照する。

toml
format = """
[╭─](bold blue) $directory$git_branch$git_status$nodejs$python$rust
[╰─](bold blue)$character"""

覚えるべき構文要素は3つだけ。

  • $variable —— 名前付きモジュールの出力に展開される(モジュールが非アクティブなら空)
  • [text](style) —— リテラル文字列にスタイルを適用する。スタイル文字列の構文はモジュール側と共通(bold green, fg:#ff5f87, bg:blue underline
  • (...) —— 括弧で囲んだグループは、中の変数がすべて空のときグループごと消える(だから言語モジュールが何もない時に「via」だけ取り残されない)

最後のルールがクリーンなプロンプトを実現するキモだ。(via [$symbol $version](bold cyan) ) と書いておけば、検出ランタイムがないときは via … ごと丸ごと消える。

個別モジュールの設定

各モジュールには専用テーブルがある。基本パターンはどれも同じで、formatsymbolstyle・必要なら disabled を設定する。

toml
[git_branch]
symbol = '🌱 '
style  = 'bold purple'
format = 'on [$symbol$branch]($style) '

[git_status]
format = '([\[$all_status$ahead_behind\]]($style) )'
style  = 'bold red'
ahead       = '⇡${count}'
behind      = '⇣${count}'
diverged    = '⇡${ahead_count}⇣${behind_count}'
conflicted  = '='
modified    = '!'
staged      = '+'
untracked   = '?'

[directory]
truncation_length = 3
truncate_to_repo  = true
read_only         = ' 🔒'
style             = 'bold cyan'

[nodejs]
format = 'via [⬢ $version](bold green) '
detect_files = ['package.json', '.nvmrc', '.node-version']

[python]
symbol = '🐍 '
format = 'via [${symbol}${pyenv_prefix}(${version} )(\($virtualenv\) )]($style)'
style  = 'yellow bold'

[kubernetes]
disabled = false        # デフォルトOFF。kubectl 漬けの人だけ ON にする
symbol   = '☸ '
format   = 'on [$symbol$context( \($namespace\))]($style) '
style    = 'cyan bold'

完全リファレンスは公式 config ドキュメントで、全モジュールの全オプションを網羅している。覚えておくと便利な一番のフラグは disabled = true|false。format 文字列を書き換えなくても、要らないモジュールはこれで止められる。

パレット: テーマを1箇所にまとめる

色を個別モジュールに直接書いてしまうと、テーマ変更が苦行になる。パレットを使えば名前付きの色を1度だけ定義して、あちこちから参照できる。

toml
palette = 'catppuccin_mocha'

[palettes.catppuccin_mocha]
rosewater = '#f5e0dc'
flamingo  = '#f2cdcd'
pink      = '#f5c2e7'
mauve     = '#cba6f7'
red       = '#f38ba8'
peach     = '#fab387'
yellow    = '#f9e2af'
green     = '#a6e3a1'
teal      = '#94e2d5'
sky       = '#89dceb'
blue      = '#89b4fa'
lavender  = '#b4befe'
text      = '#cdd6f4'
surface0  = '#313244'
base      = '#1e1e2e'
mantle    = '#181825'
crust     = '#11111b'

[character]
success_symbol = '[❯](bold green)'
error_symbol   = '[❯](bold red)'

[git_branch]
style = 'bold mauve'

[directory]
style = 'bold blue'

Catppuccin Mocha から Tokyo Night に切り替えたいときは、トップレベルの palette を1行書き換えるだけ。同じファイルにパレットを複数定義しておけば、1行で全モジュールの配色がまとめて変わる。

プリセット: Tokyo Night、Gruvbox Rainbow、Pure ほか

ゼロから書くのが面倒なら、Starship には公式プリセットギャラリーがある。人気のテーマ用 starship.toml がそのまま落ちてくるので、1コマンドで適用できる。

bash
# 公式プリセット12種、すべて同じ書式でインストール可能
starship preset nerd-font-symbols   -o ~/.config/starship.toml
starship preset no-nerd-font        -o ~/.config/starship.toml
starship preset bracketed-segments  -o ~/.config/starship.toml
starship preset plain-text-symbols  -o ~/.config/starship.toml
starship preset no-runtime-versions -o ~/.config/starship.toml
starship preset no-empty-icons      -o ~/.config/starship.toml
starship preset pure-preset         -o ~/.config/starship.toml
starship preset pastel-powerline    -o ~/.config/starship.toml
starship preset tokyo-night         -o ~/.config/starship.toml
starship preset gruvbox-rainbow     -o ~/.config/starship.toml
starship preset jetpack             -o ~/.config/starship.toml
starship preset catppuccin-powerline -o ~/.config/starship.toml

実際にユーザーが選びがちなプリセットは4つ。

  • tokyo-night —— tokyo-night-vscode-theme ベースのダーク系。冷たい青紫の配色で、行の区切りもクリーン。Starship 関連で一番人気のダークプリセットで、r/starship_prompt のスクリーンショットで頻出する。
  • gruvbox-rainbow —— アースカラー系の暖色 + パワーライン形式の矢印セグメント。r/unixporn のスクショ映えプリセットの代表格。
  • pure-preset —— JavaScript 製の Pure prompt を模した1行ミニマルプロンプト。アイコンが煩く感じる人向けのスパルタン構成。
  • pastel-powerline —— パステル系パワーラインで、パス置換機能(~/Documents をフォルダアイコンに、~/.config を歯車に置き換え等)が入っている。M365Princess テーマインスパイア。

カスタムモジュールと応用パターン

ビルトインモジュールでだいたいのことは賄えるが、いずれ「自分のコマンドを走らせて結果を表示したい」場面が出てくる。それが [custom.NAME] で、Starship と任意の CLI ツールを繋ぐ橋になる。

カスタムモジュールの実例

toml
# direnv が有効ならその環境名を表示する
[custom.direnv]
command = 'echo "$DIRENV_DIR" | sed "s|^.*/||"'
when    = '[ -n "$DIRENV_DIR" ]'
format  = 'env [$output]($style) '
style   = 'bold purple'
shell   = ['bash', '--noprofile', '--norc']
description = 'direnv 環境がアクティブなら表示する'

# 1Password CLI のアクティブアカウントを表示
[custom.op_account]
command = 'op account list --format=json | jq -r ".[0].shorthand"'
when    = 'command -v op'
format  = '[$output 🔑]($style) '
style   = 'bold yellow'
shell   = ['bash', '--noprofile', '--norc']

# 上記2つを format 文字列から参照
format = """
$directory $git_branch $git_status \
${custom.direnv}${custom.op_account}\
$character
"""

必須フィールドは4つ。command(実行するシェルコマンド)、when(ガード条件——非0終了ならモジュールはスキップされる)、format$output のレンダリング指定)、shell(呼び出すシェル)。description フィールドは starship explain で表示されるので、未来の自分のためのドキュメントとして書いておくといい。

Transient prompt(過去プロンプトの圧縮)

Transient prompt は、Enter を押した瞬間に直前のプロンプトを別の(だいたいもっと短い)プロンプトに置き換えてくれる機能で、スクロールバックを綺麗に保てる。zsh / fish / bash / PowerShell でサポートされている。zsh の場合の最小構成は次の通り。

toml
# starship.toml には特別な設定不要

# ~/.zshrc の starship init より後に:
# eval "$(starship init zsh --print-full-init)"
# zle-line-init() { zle reset-prompt; }
# zle -N zle-line-init

シェルごとの完全な手順はアドバンス設定ドキュメントにある。bash・fish・PowerShell それぞれのスニペットが載っている。有効にしたあとは、スクロールバックには ❯ command だけが残るようになり、複数行プロンプトが履歴を埋め尽くさない。

Pre-prompt と Pre-execution フック

Starship は「プロンプト描画前」「コマンド実行前」に走る関数をフックできる。日次メッセージや通知の発火に便利だ。

bash
# ~/.bashrc
function blastoff() { echo "🚀"; }
starship_precmd_user_func="blastoff"

これでプロンプトの前に毎回 🚀 が出る。同じ変数名(starship_precmd_user_func)が zsh でも動く。fish や PowerShell には別の同等機能がある——詳細はアドバンス設定ページ

STARSHIP_CONFIG でプロジェクト別設定

環境変数 STARSHIP_CONFIG に任意の TOML ファイルパスを設定すれば、Starship はデフォルト位置の代わりにそれを読む。

bash
export STARSHIP_CONFIG=~/.config/starship-work.toml

direnvと組み合わせれば、家ではレインボーでアイコン全部入りのプロンプト、仕事中はミニマルで AWS モジュールも切ったプロンプト(顧客名が画面共有に映らない)と使い分けられる。

FAQ

Q. 本当に powerlevel10k より速いの? プロンプトを実際にレンダリングする時間で言えば速い。Starship は単一の Rust バイナリで全モジュールを並列実行するので、ほとんどのリポで 1〜10ms で描画が終わる。powerlevel10k は「instant prompt」テクニック(古いプロンプトを先に表示しつつ裏で本物を計算する)で「速く見せる」設計で、初回の体感はもっと速いこともある。日常使いでどちらも十分速いので差は意識しないだろう。Starship 側の本当の利点は、bash・fish・PowerShell でも同じ速度で動くこと——zsh だけが速いわけではない。

Q. oh-my-zsh はアンインストールする必要がある? ない。Starship は zsh init の最後にプロンプトだけを上書きする。oh-my-zsh のプラグインや補完フレームワークやエイリアスはそのまま動く。差し替わるのは見た目のプロンプトだけ。

Q. デフォルト設定の中身を見るには? starship print-config --default を流せばビルトインの TOML が全部標準出力に出る。気に入った部分を ~/.config/starship.toml にコピーしていけばいい。starship explain も便利で、カレントディレクトリでどのモジュールが発火していて、それぞれ何ミリ秒かかったかが見える。プロンプトのデバッグに最適。

Q. プロンプトが急に遅くなった。原因の特定方法は? starship timings を実行する。直前の描画で各モジュールが消費した壁時計時間が、遅い順にソートされて出てくる。シェルコマンドを呼ぶカスタムモジュールが犯人になりがち。次に多いのは、pythonnodejs モジュールが遅いファイルシステム(NFS、FUSE、暗号化ホーム)を踏むケース。そのディレクトリでだけ STARSHIP_CONFIG を使ってモジュールを disabled にすればいい。

Q. SSH 経由や tmux 内でも動く? 動く。Starship バイナリはサーバ側に置く(ローカルのバイナリを使うのではない)。サーバに starship を入れて、サーバ側 bashrc に eval 行を追加すれば終わり。ビルトインの hostname モジュールは SSH セッションのときだけホスト名を出すので、ローカルでは普通の見た目、リモート接続時だけホスト名が増える、という賢い挙動になる。

Q. プロジェクトごとに違うプロンプトを使える? 使える。STARSHIP_CONFIG に別の TOML ファイルを指すように設定すればいい。一番きれいな実装は direnvと組み合わせる方法で、.envrcexport STARSHIP_CONFIG=$PWD/.starship.toml と書いておけば、cd した瞬間に direnv が読み込んでくれる。dotfiles 管理の作法と組み合わせるとそのまま Git 管理できる。

Q. macOS 26 にしたら Nerd Font アイコンが消えたんだけど? macOS 26 のターミナルのデフォルトフォントが Nerd Font グリフを含まないものに変わった。Nerd Font(FiraCode、JetBrainsMono、Hack 等)を入れ直して、Terminal.app か iTerm2 の設定で再選択すれば直る。Starship 自体は macOS のリリース間で挙動が変わっていない——常にフォント側の問題。

Q. なぜ Rust で書かれているのか、Rust じゃないとダメ? 実用上はダメ。プロンプトはシェルコマンドを打つたびに走るので、GC ポーズや fork-exec のオーバーヘッドや起動コストが積み重なる。Starship は .git/HEAD を読み、package.json をパースし、kubernetes コンテキストを確認し、それを毎回数 ms で終わらせる必要がある。Rust ならゼロコスト抽象化と GC 不在で最悪レイテンシが小さく抑えられる。Go でも書けるが、ゼロコストイテレータと GC ポーズ非依存というレイヤでは Rust が有利——詳細はRust製CLIツールはなぜ速いのかで解説している。

まとめ

Starship はシェルが変わってもマシンが変わっても残り続ける、1ファイル完結のプロンプトだ。本記事で押さえてほしい4点。

  1. インストール1回、設定1ファイルcurl -sS https://starship.rs/install.sh | sheval 1行、~/.config/starship.toml 1ファイルで完結する。
  2. プリセットから始めるstarship preset tokyo-night -o ~/.config/starship.toml を流して、そこから少しずつ手を入れる方が楽。ゼロから書くのは趣味の人だけ。
  3. テーマはパレットで管理する[palettes.NAME] に色を1度だけ定義して、各モジュールから参照する。アクティブパレットの切り替えは1行で済む。
  4. 遅くなったら starship timings。どのモジュールが遅いかをそのまま教えてくれる。

Starship はモダンCLIシリーズの他のツールと自然に連携する。シンタックスハイライト付きで cat を置き換える bat、git diff を読みやすくする deltagrep を置き換える ripgrep、ファジー検索の fzf、GitHub 操作の gh CLI——それらを束ねる「土台」がプロンプトだ。starship.toml をシェル設定と一緒に Git 管理する作法はdotfiles ガイドに、Rust 製 CLI が速い技術背景はRust製CLIツールはなぜ速いのかにある。