Project 3: Custom Shell Prompt (Starship or Pure Prompt)
Build a fast, information-dense prompt that stays readable in any repo.
Quick Reference
| Attribute | Value |
|---|---|
| Difficulty | Level 2 (Intermediate) |
| Time Estimate | 4-8 hours |
| Main Language | Shell config (Starship or Pure) |
| Prerequisites | Shell startup knowledge, basic Git awareness |
| Key Topics | Prompt rendering, async git status, performance budgets |
1. Learning Objectives
By completing this project, you will:
- Design a prompt layout that balances information and clarity.
- Configure prompt segments for git status, runtime version, and directory.
- Keep prompt rendering fast with caching or async updates.
- Implement prompt theming that matches your terminal palette.
- Create machine-specific overrides without forking the prompt config.
2. Theoretical Foundation
2.1 Core Concepts
- Prompt Segments: Structured pieces of data (path, git, time, language) rendered consistently.
- Git Status Cost: Computing git status can be expensive in large repos.
- Async vs Sync Prompts: Async prompts improve responsiveness by updating after the prompt renders.
- Color and Contrast: Prompt readability depends on color choices and minimal noise.
2.2 Why This Matters
Your prompt is the dashboard of your CLI. A well-designed prompt reduces context switching and prevents mistakes (like committing on the wrong branch). A bad prompt is noisy, slow, or misleading. This project teaches you to treat prompt configuration as an interface design problem with a performance budget.
2.3 Historical Context / Background
Traditional prompts were static (user@host:path$). Modern tools like Powerlevel10k, Pure, and Starship added context-aware segments (git state, language version, time). The key challenge became performance: showing rich data without slowing every command.
2.4 Common Misconceptions
- “More segments are always better”: Too many segments reduce signal and slow rendering.
- “Git status is free”: Large repos can make prompts slow unless optimized.
- “Prompt config is cosmetic”: It shapes workflow accuracy and speed.
3. Project Specification
3.1 What You Will Build
A custom prompt configuration that:
- Shows current directory, git branch, and git status summary
- Displays language runtime version when relevant (e.g., node, python)
- Indicates command success/failure
- Renders in under 100ms on large repos
- Supports light/dark terminal themes
3.2 Functional Requirements
- Core Segments: path, git branch, git status, exit code.
- Language Segment: show runtime version when project contains relevant files.
- Status Indicators: show clean/dirty, ahead/behind.
- Performance: prompt renders quickly even in large repos.
- Toggle: allow prompt to be simplified via env var (e.g.,
PROMPT_MINIMAL=1).
3.3 Non-Functional Requirements
- Performance: < 100ms render in large repos.
- Usability: high contrast and predictable layout.
- Portability: works across macOS and Linux.
3.4 Example Usage / Output
~/work/api-service main ⇡1 ●2 node v20.10.0 ✓
$
3.5 Data Formats / Schemas
Use Starship TOML or shell config:
[git_branch]
format = "[$branch]($style)"
3.6 Edge Cases
- Repo with 10k+ files causes slow git status.
- Detached HEAD or no branch name.
- Path length too long for small terminal width.
- Non-git directories should not show git segments.
3.7 Real World Outcome
You open a terminal and immediately see the right branch, a clean/dirty indicator, and relevant runtime version, without delay. In big repos, the prompt remains fast and your workflow stays smooth.
4. Solution Architecture
4.1 High-Level Design
Shell -> Prompt Engine -> Segments -> Rendered Prompt
| |
v v
config file git/status checks
4.2 Key Components
| Component | Responsibility | Key Decisions |
|---|---|---|
| prompt config | defines layout and colors | keep it minimal and consistent |
| git segment | branch/status info | cache or async for speed |
| status segment | exit code display | show only on failure |
4.3 Data Structures (No Full Code)
[status]
format = "[$status]($style)"
disabled = false
4.4 Algorithm Overview
Prompt Rendering Flow
- Shell invokes prompt engine.
- Engine reads config and determines segments.
- Git segment checks repo status and caches if needed.
- Segments render to a single string.
Complexity Analysis:
- Time: O(segments + git status)
- Space: O(1)
5. Implementation Guide
5.1 Development Environment Setup
# Starship example
brew install starship
5.2 Project Structure
~/dotfiles/
├── prompt/
│ └── starship.toml
└── shell/
└── prompt.zsh
5.3 The Core Question You Are Answering
“How do I design a prompt that gives high-signal context without slowing me down?”
5.4 Concepts You Must Understand First
- Git Status Performance
- Why
git statusis expensive in large repos - How caching or async updates help
- Why
- Prompt Segment Design
- What belongs in the prompt vs optional commands
- Visual hierarchy and spacing
- Exit Status Semantics
- How
$?represents the previous command - When to display success vs failure
- How
5.5 Questions to Guide Your Design
- What information prevents mistakes (wrong branch, dirty repo)?
- Which segments are optional and should be hidden by default?
- How will you keep the prompt readable in a narrow terminal?
- What is your maximum acceptable latency?
5.6 Thinking Exercise
Sketch your ideal prompt in a text editor. Count characters and evaluate how it looks at 80 columns.
5.7 The Interview Questions They Will Ask
- Why can git status slow down prompts?
- How do async prompts work conceptually?
- What makes a prompt “good” for developer experience?
5.8 Hints in Layers
Hint 1: Start with path + git branch only.
Hint 2: Add git status symbols (dirty/clean).
Hint 3: Add language version segments conditionally.
5.9 Books That Will Help
| Topic | Book | Chapter |
|---|---|---|
| Shell ergonomics | Effective Shell | Ch. 20-21 |
| UX clarity | The Pragmatic Programmer | Ch. 2 |
5.10 Implementation Phases
Phase 1: Minimal Prompt (1-2 hours)
Goals:
- Install prompt engine
- Configure path + git branch
Checkpoint: Prompt renders with branch info.
Phase 2: Status and Versioning (2-3 hours)
Goals:
- Add git status symbols
- Add language runtime segments
Checkpoint: Prompt shows dirty/clean state and version.
Phase 3: Performance and Polish (1-2 hours)
Goals:
- Add caching or async settings
- Configure colors for readability
Checkpoint: Prompt renders < 100ms in large repo.
5.11 Key Implementation Decisions
| Decision | Options | Recommendation | Rationale |
|---|---|---|---|
| Prompt engine | Starship vs Pure | Starship | Cross-shell and fast |
| Git status style | full vs minimal | minimal | Avoid noise and cost |
| Status display | always vs on error | on error | Reduces clutter |
6. Testing Strategy
6.1 Test Categories
| Category | Purpose | Examples |
|---|---|---|
| Performance Tests | Render speed | time zsh -i -c exit |
| Visual Tests | Readability | dark/light theme check |
| Git State Tests | Correct status | dirty/clean branch indicator |
6.2 Critical Test Cases
- Large repo: prompt remains responsive.
- Detached HEAD: branch segment shows fallback.
- Non-git directory: git segments hidden.
6.3 Test Data
Use a large repo (e.g., Linux kernel) and compare prompt latency.
7. Common Pitfalls and Debugging
| Pitfall | Symptom | Solution |
|---|---|---|
| Slow prompt | noticeable lag | enable async/caching |
| Overloaded prompt | cluttered display | remove low-value segments |
| Wrong colors | unreadable text | adjust palette and contrast |
7.2 Debugging Strategies
- Temporarily disable segments to isolate the slow one.
- Use
STARSHIP_LOG=debugto inspect performance.
8. Extensions and Challenges
8.1 Beginner Extensions
- Add a time segment that shows only in long commands.
- Add a jobs segment when background tasks exist.
8.2 Intermediate Extensions
- Add a Kubernetes context segment.
- Add a virtualenv indicator for Python projects.
8.3 Advanced Extensions
- Build a custom segment that reads from a local JSON file.
- Implement async git status using custom scripts.
9. Real-World Connections
9.1 Industry Applications
- Preventing mistakes in multi-repo environments
- Improving developer onboarding with consistent prompts
- Making CI logs easier to read
9.2 Related Open Source Projects
- starship: Cross-shell prompt engine
- powerlevel10k: High-performance zsh theme
9.3 Interview Relevance
- Demonstrates UX thinking, performance awareness, and shell knowledge.
10. Resources
10.1 Essential Reading
- Effective Shell (Ch. 20-21)
- Starship documentation
10.2 Tools and Documentation
- Starship TOML reference
- Pure prompt docs
10.3 Related Projects in This Series
- Project 1: Shell Alias System
- Project 10: Terminal Emulator Configuration
11. Self-Assessment Checklist
11.1 Understanding
- I can explain why git status impacts prompt speed
- I can design a prompt layout with visual hierarchy
- I can interpret exit status display
11.2 Implementation
- Prompt renders with path + git + status segments
- Prompt is fast in large repos
- Config is versioned and documented
11.3 Growth
- I can extend the prompt with custom segments
- I know how to debug slow prompts
12. Submission / Completion Criteria
Minimum Viable Completion:
- Prompt shows path and git branch
- Prompt renders quickly in normal repos
Full Completion:
- Status + runtime segments included
- Performance budget verified
Excellence (Going Above and Beyond):
- Async/cached git status
- Custom segment integrated