Yes, this is a very common problem with putting API calls in prompts! If you run it synchronously, your terminal freezes for a half-second every time you press Enter.
To fix this, we can create a smart wrapper script. The script will:
- Immediately read from a
/tmp/cache file so your prompt is instantaneous (zero lag). - Fetch from GitHub in the background if the cache is missing or older than 24 hours.
- Provide a
--refreshflag so you can manually update it right after opening a new PR.
Here is the complete setup to get this working perfectly:
Create a new file for the script. A good standard place is ~/.local/bin/.
mkdir -p ~/.local/bin
nano ~/.local/bin/gh_pr_prompt.shPaste the following bash script inside:
#!/usr/bin/env bash
# Exit immediately if we aren't in a git repo
REPO_PATH=$(git rev-parse --show-toplevel 2>/dev/null) || exit 0
BRANCH=$(git branch --show-current 2>/dev/null)
[ -z "$BRANCH" ] && exit 0
# Create a safe, unique cache filename for this specific repo + branch
SAFE_REPO=$(basename "$REPO_PATH")
SAFE_BRANCH=$(echo "$BRANCH" | tr '/' '_')
CACHE_FILE="/tmp/starship_gh_pr_${SAFE_REPO}_${SAFE_BRANCH}"
# Handle manual cache refresh (e.g., when you just created a new PR)
if [ "$1" == "--refresh" ]; then
echo "Fetching PR data from GitHub..."
PR=$(gh pr view "$BRANCH" --json number -q .number 2>/dev/null)
if [ -n "$PR" ]; then
echo "$PR" > "$CACHE_FILE"
echo "✅ Cache updated: PR #$PR"
else
echo "none" > "$CACHE_FILE"
echo "✅ Cache updated: No PR found for this branch"
fi
exit 0
fi
# Function to fetch PR in the background so the prompt never hangs!
update_cache_in_background() {
{
PR=$(gh pr view --json number -q .number 2>/dev/null)
if [ -n "$PR" ]; then
echo "$PR" > "$CACHE_FILE"
else
echo "none" > "$CACHE_FILE"
fi
} >/dev/null 2>&1 &
}
# Check if cache is missing or older than 24 hours (1440 minutes)
if [ ! -f "$CACHE_FILE" ]; then
# First time seeing this branch. Show loading dots and fetch in background.
echo "⏳" > "$CACHE_FILE"
update_cache_in_background
elif [ -n "$(find "$CACHE_FILE" -mmin +1440 2>/dev/null)" ]; then
# Cache is stale (> 24h). Touch it to reset timer so we don't spawn multiple jobs, then fetch.
touch "$CACHE_FILE"
update_cache_in_background
fi
# Read and output the cache for Starship
VAL=$(cat "$CACHE_FILE" 2>/dev/null)
if [ "$VAL" != "none" ] && [ "$VAL" != "⏳" ] && [ -n "$VAL" ]; then
echo "$VAL"
elif [ "$VAL" == "⏳" ]; then
echo "..."
fiMake the script executable:
chmod +x ~/.local/bin/gh_pr_prompt.shNow, edit your ~/.config/starship.toml to use this new script instead of running gh directly:
[custom.gh_pr]
description = "Show GitHub PR number with background caching"
command = "~/.local/bin/gh_pr_prompt.sh"
when = "git rev-parse --is-inside-work-tree 2>/dev/null"
format = "with [🐈⬛ PR #$output]($style) "
style = "bold purple"Since the script only auto-updates once every 24 hours, you'll want a way to force an update when you actively open a new PR on your current branch.
Add this alias to your ~/.bashrc or ~/.zshrc:
alias pr-refresh="~/.local/bin/gh_pr_prompt.sh --refresh"(Don't forget to run source ~/.bashrc or source ~/.zshrc after adding it!)
- Zero Lag: The prompt will always draw instantly because it just reads a tiny text file in
/tmp/. - First time on a branch: It will briefly display
[🐈⬛ PR #...]on your prompt while it asks GitHub in the background. The next time you press Enter, it will have the number. - No PR exists: If you aren't working on a PR, the background task writes "none" to the cache, and the module hides itself completely so it doesn't clutter your prompt.
- Forcing an update: Just type
pr-refreshin your terminal and it will ping GitHub and update the cache file immediately.