Starship es un único binario en Rust que reemplaza el prompt de cualquier shell — bash, zsh, fish, PowerShell, Nushell, Cmd — con un solo archivo TOML (~/.config/starship.toml). El resultado es concreto: un prompt consciente del contexto que muestra la rama de git, la versión del runtime, el contexto de Kubernetes y la duración del comando, sin esperar a subshells, así que se mantiene instantáneo incluso en monorepos enormes. Lo instalas con un curl, añades una línea eval a tu rc del shell y starship.toml se convierte en el único lugar donde editas tu prompt — en cualquier máquina, cualquier shell, cualquier proyecto.
Ya conoces el dolor. Escribiste un PS1 perfecto en bash en 2018, lo copiaste a todos tus dotfiles y ahora la mitad no se renderiza en zsh, el bloque de git status añade 400 ms a cada comando, y los colores se ven mal en el MacBook nuevo porque la terminal usa otro esquema. Después trabajas con alguien cuyo prompt muestra la cuenta de AWS, el namespace de Kubernetes y el venv de Python en una sola línea, y acabas buscando "cómo hacer un prompt bonito en bash" a medianoche.
Starship es la respuesta que la mayoría de desarrolladores acaba adoptando. Es un binario en Rust que renderiza en ~1 ms, soporta todos los shells importantes desde una sola configuración, viene con más de 100 módulos sensibles al contexto y guarda toda su configuración en ~/.config/starship.toml. En este artículo recorremos la instalación, los módulos por defecto, la personalización paso a paso de starship.toml, los presets como Gruvbox Rainbow y Tokyo Night, y cómo escribir tus propios módulos personalizados. Al final tendrás un único archivo de configuración del prompt que puedes copiar a cualquier máquina.
Por qué Starship en lugar de bash, oh-my-zsh o powerlevel10k
Bash con PS1, los temas de oh-my-zsh y powerlevel10k existen por buenas razones. Las cuatro razones prácticas para reemplazarlos por Starship son:
- Una configuración, todos los shells. Un solo
~/.config/starship.tomlfunciona en bash, zsh, fish, PowerShell, Cmd, Nushell, Xonsh, Ion y Elvish. Si cambias de shell — o tus colegas usan otro distinto — tu prompt te sigue sin reescribir nada. - Velocidad real, no aparente. Powerlevel10k se ganó su fama con el truco del "instant prompt" (mostrar un prompt obsoleto mientras se calcula el real en segundo plano). Starship es lo bastante rápido como para no necesitar ese truco — un render típico tarda entre 1 y 10 ms porque cada módulo está implementado en Rust y se ejecuta en paralelo dentro de un único binario, sin forks de subshell.
- Más de 100 módulos sensibles al contexto. Trae módulos integrados para git, más de 40 runtimes (Node.js, Python, Rust, Go, Java, Kotlin, Ruby, PHP, Dart, Deno, Bun, Zig, Nim, OCaml, Crystal, Elixir, Erlang, Haskell, Lua, Perl, Scala, Swift, Typst, etc.), nubes (AWS, Azure, GCP, OpenStack), DevOps (contexto de Docker y Kubernetes, Helm, Terraform, Pulumi) e info del sistema (batería, hora, OS, hostname). Se activan automáticamente según los archivos del directorio actual — sin interruptores manuales.
- Defaults sensatos. Ejecutas
starship inituna vez y el prompt por defecto ya es útil: directorio, rama de git, estado de git, versión del runtime, duración del comando y un símbolo de prompt en color. Lo instalas en una máquina nueva y en 30 segundos tienes un prompt funcional.
El lenguaje de implementación es Rust (starship/starship) — y a diferencia del artículo anterior de la serie (gh CLI, escrito en Go), Rust es la decisión correcta aquí porque cada milisegundo cuenta. Un prompt corre en cada comando del shell, así que el coste de una implementación pesada o con GC se acumula muy rápido. Starship mantiene el render por debajo de los 10 ms incluso cuando tiene que leer tu .git/HEAD, parsear package.json y consultar el contexto de Kubernetes — todo en paralelo.
Instalar Starship y conectarlo a tu shell
Dos pasos: instalar el binario y añadir una línea al rc del shell. La página oficial de instalación lista todas las plataformas; el resumen está abajo.
# winget (incluido en Windows 11)
winget install --id Starship.Starship
# o Scoop
scoop install starship
# o Chocolatey
choco install starship
Verifica el binario después de instalar:
starship --version
# starship 1.24.2
Ahora conéctalo al shell. Coge el snippet del shell que usas y pégalo en el rc correspondiente:
# ~/.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
Abre un shell nuevo y el prompt ya está reemplazado. Aún no existe ningún starship.toml — y eso es a propósito. Los defaults son lo bastante buenos como para que la mayoría de usuarios pase semanas antes de tocar un archivo de configuración.
Los módulos por defecto: qué ves y por qué
Lanza Starship recién instalado en cualquier directorio y el prompt se ve más o menos así:
~/projects/32blog on master [!?] via v22.13.0
❯
Cada segmento es un módulo que se activa según el contexto. Los defaults son intencionalmente minimalistas — Starship oculta los módulos cuyos datos están vacíos. Esto es lo que significa cada parte y qué módulo lo produjo, en orden:
| Segmento | Módulo | Cuándo aparece | Qué muestra |
|---|---|---|---|
~/projects/32blog | directory | Siempre | Directorio actual, truncado a 3 segmentos por defecto; resalta la raíz del repo en cian |
on master | git_branch | Dentro de un repo git | Nombre de la rama con el glifo de Nerd Font |
[!?] | git_status | Cuando hay cambios en el árbol de trabajo | Símbolos para staged (+), modified (!), untracked (?), conflicted (=), ahead/behind (⇡⇣), stashed ($) |
via v22.13.0 | nodejs (y otros 25) | Cuando existe package.json o .nvmrc | Runtime detectado y versión |
❯ | character | Siempre | Verde si el comando anterior tuvo éxito, rojo si falló |
La cadena de formato del prompt por defecto es la variable mágica $all, que se expande a los más de cien módulos de Starship en orden fijo. Para ver el default completo, ejecuta:
starship print-config --default
Ese comando vuelca el TOML interno por defecto a stdout. Copia las partes que te interesen a tu propio ~/.config/starship.toml y modifícalas — esa es la forma canónica de empezar a personalizar.
Un malentendido común es que todos los módulos se ejecutan siempre. No es así. Cada módulo tiene una comprobación "¿debo activarme?" que corre antes de producir cualquier output, y Starship las ejecuta todas en paralelo. El módulo nodejs busca package.json, .node-version, .nvmrc o archivos *.js; el módulo python busca requirements.txt, pyproject.toml, Pipfile o *.py; el módulo kubernetes viene con disabled = true por defecto y hay que activarlo a mano. Por eso el prompt sigue siendo rápido — la mayoría de módulos no producen output y terminan en microsegundos.
Configurar starship.toml: cadenas de formato, módulos y paletas
~/.config/starship.toml es el único archivo que vas a editar. La configuración mínima útil son unas pocas líneas:
# ~/.config/starship.toml
"$schema" = 'https://starship.rs/config-schema.json'
# Línea en blanco antes de cada prompt
add_newline = true
# Espera máxima por módulo (ms)
command_timeout = 500
# Símbolo personalizado según el código de salida
[character]
success_symbol = '[➜](bold green)'
error_symbol = '[✗](bold red)'
# Mostrar duración solo si el comando tarda ≥ 2 s
[cmd_duration]
min_time = 2_000
format = 'took [$duration]($style) '
style = 'bold yellow'
Guarda, abre un shell nuevo y los cambios se aplican. Starship vuelve a leer el archivo en cada renderización del prompt — no hay daemon que reiniciar.
Cómo funciona la cadena de formato
La opción format de nivel superior decide qué módulos se renderizan y en qué orden. El default es la variable mágica $all. Para personalizar el layout, escribe tu propia cadena de formato y referencia los módulos con $nombre_modulo:
format = """
[╭─](bold blue) $directory$git_branch$git_status$nodejs$python$rust
[╰─](bold blue)$character"""
Tres piezas de sintaxis importan:
$variable— se expande al output del módulo (o vacío si el módulo está inactivo)[texto](style)— envuelve texto literal en un estilo; el estilo sigue la misma sintaxis que los estilos de módulo (bold green,fg:#ff5f87,bg:blue underline)(...)— un grupo entre paréntesis se oculta entero si todas las variables dentro están vacías (así no te queda unviahuérfano cuando no hay módulo de lenguaje)
Esa última regla es el secreto de un prompt limpio: puedes escribir (via [$symbol $version](bold cyan) ) y todo el bloque via … desaparece cuando no hay runtime detectado.
Configurar módulos individuales
Cada módulo tiene su propia tabla. El patrón es siempre el mismo: define format, symbol, style y opcionalmente disabled:
[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 por defecto — actívalo si vives en kubectl
symbol = '☸ '
format = 'on [$symbol$context( \($namespace\))]($style) '
style = 'cyan bold'
La referencia completa son los docs de configuración, que listan cada opción de cada módulo. La bandera más útil de recordar es disabled = true|false — puedes apagar cualquier módulo que no quieras sin tocar la cadena de formato.
Paletas: tematizar todo desde un solo sitio
Si cambias colores directamente dentro de cada módulo, cambiar de tema se vuelve un suplicio. Las paletas resuelven esto — define colores con nombre una vez y úsalos desde todas partes:
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'
Cambiar de Catppuccin Mocha a Tokyo Night ahora es modificar una sola línea: el palette de nivel superior. Define varias paletas en el mismo archivo, alterna con una sola edición y todos los módulos cambian a la vez.
Presets: Tokyo Night, Gruvbox Rainbow, Pure y compañía
Si escribir tu config desde cero suena tedioso, Starship trae una galería de presets — archivos starship.toml completos para los looks más populares. Instalas uno con un solo comando:
# Los 12 presets oficiales, todos se instalan igual
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
Los cuatro presets que la gente acaba eligiendo en la práctica:
tokyo-night— paleta oscura azul-violeta inspirada en el tokyo-night-vscode-theme. El preset oscuro más popular en el subreddit de Starship — filas limpias, sin flechas powerline.gruvbox-rainbow— tonos cálidos terrosos con flechas de segmento estilo powerline. El preset "vistoso" reinante, usado en docenas de capturas en r/unixporn.pure-preset— prompt minimalista de una sola línea que imita el Pure prompt de JavaScript. Lo mejor si los iconos te resultan ruidosos y prefieres un look espartano.pastel-powerline— segmentos powerline en tonos pastel con sustitución de paths (reemplaza~/Documentscon un icono de carpeta,~/.configcon un engranaje, etc.). Inspirado en el tema M365Princess.
Módulos personalizados y patrones avanzados
Los módulos integrados cubren casi todo, pero tarde o temprano querrás algo a medida — un módulo que ejecute tu propio comando y muestre el resultado. Eso es [custom.NOMBRE], y es el puente entre Starship y cualquier herramienta con CLI.
Ejemplo de módulo personalizado
# Mostrar el entorno direnv activo, si lo hay
[custom.direnv]
command = 'echo "$DIRENV_DIR" | sed "s|^.*/||"'
when = '[ -n "$DIRENV_DIR" ]'
format = 'env [$output]($style) '
style = 'bold purple'
shell = ['bash', '--noprofile', '--norc']
description = 'Muestra el entorno direnv si está activo'
# Mostrar la cuenta activa del CLI de 1Password
[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']
# Referencia ambos en la cadena de formato
format = """
$directory $git_branch $git_status \
${custom.direnv}${custom.op_account}\
$character
"""
Los cuatro campos requeridos son command (el comando del shell a ejecutar), when (una condición de guarda — si sale con código distinto de cero, el módulo se salta a sí mismo), format (cómo renderizar $output) y shell (qué shell invocar). El campo description aparece en starship explain y es buena documentación para tu yo del futuro.
Transient prompts (compactar el prompt previo)
Un transient prompt es un prompt diferente (normalmente más corto) que reemplaza al anterior una vez pulsas Enter, así tu scrollback se mantiene limpio. Está soportado en zsh, fish, bash y PowerShell. El patrón en zsh se ve así:
# En starship.toml — nada especial
# En ~/.zshrc, después de la línea de starship init:
# eval "$(starship init zsh --print-full-init)"
# zle-line-init() { zle reset-prompt; }
# zle -N zle-line-init
La configuración completa por shell está en los docs avanzados — bash, fish y PowerShell tienen cada uno su propio snippet. Una vez activado, tu scrollback solo muestra ❯ comando para cada prompt previo, en lugar del prompt multilínea completo.
Hooks pre-prompt y pre-execution
Starship te permite enganchar una función para que corra antes de cada prompt o antes de cada comando. Útil para efectos secundarios puntuales como un mensaje diario o una notificación:
# En ~/.bashrc
function blastoff() { echo "🚀"; }
starship_precmd_user_func="blastoff"
Ahora 🚀 se imprime antes de cada prompt. El mismo nombre de variable (starship_precmd_user_func) funciona en zsh; fish y PowerShell tienen sus propios equivalentes documentados en la página de configuración avanzada.
STARSHIP_CONFIG y configs por proyecto
Define la variable de entorno STARSHIP_CONFIG apuntando a cualquier archivo TOML y Starship lo usará en lugar de la ubicación por defecto:
export STARSHIP_CONFIG=~/.config/starship-work.toml
Combinado con direnv, puedes tener un prompt en casa (rainbow, lleno de iconos) y otro distinto en el trabajo (mínimo, sin módulo de AWS para que el nombre del cliente no acabe en pantallas compartidas).
FAQ
Q. ¿Starship es realmente más rápido que powerlevel10k? Para el render efectivo del prompt, sí — Starship renderiza en 1–10 ms en la mayoría de repos porque todo es un único binario en Rust ejecutando módulos en paralelo. Powerlevel10k usa el truco del "instant prompt" para parecer rápido (muestra un prompt obsoleto mientras calcula el real), lo cual puede sentirse aún más rápido en el primer render. En el día a día, los dos son lo bastante rápidos como para no notar la diferencia. La ventaja real de Starship es que tiene la misma velocidad en cualquier shell — bash, fish, PowerShell — no solo en zsh.
Q. ¿Tengo que desinstalar oh-my-zsh? No. Starship sobrescribe solo el prompt al final del init de zsh. Los plugins, frameworks de autocompletado y aliases de oh-my-zsh siguen funcionando. Lo único que se reemplaza es el prompt visual.
Q. ¿Cómo veo qué hay en la configuración por defecto?
Ejecuta starship print-config --default. Vuelca el TOML interno completo a stdout — copia las partes que quieras a tu propio ~/.config/starship.toml. También está starship explain, que muestra qué módulos se están disparando en el directorio actual y cuánto tardó cada uno, útil para debuggear prompts lentos.
Q. Mi prompt se volvió lento de pronto. ¿Cómo encuentro al culpable?
starship timings es la respuesta. Lánzalo en cualquier directorio e imprime el tiempo de pared que cada módulo consumió en el último render, ordenado de más lento a más rápido. Los módulos custom con comandos de shell son los sospechosos habituales. La otra causa común es que python o nodejs toquen un sistema de archivos lento (NFS, FUSE, home cifrado) — desactiva el módulo en ese directorio con un toggle [disabled] en STARSHIP_CONFIG.
Q. ¿Funciona Starship por SSH y dentro de tmux?
Sí. El binario vive en la máquina remota, no en la local — instala starship en el servidor, añade la línea eval al bashrc del servidor y listo. Hay incluso un módulo hostname integrado que muestra el host solo cuando estás en una sesión SSH, así que tu prompt se ve normal en local pero añade el hostname cuando te conectas remotamente.
Q. ¿Puedo tener un prompt diferente para cada proyecto?
Sí — apunta STARSHIP_CONFIG a un archivo TOML distinto. La forma más limpia es vía direnv: pon export STARSHIP_CONFIG=$PWD/.starship.toml en el .envrc de un proyecto y direnv lo carga al hacer cd. Combínalo con la guía de dotfiles para versionarlo todo.
Q. ¿Por qué desaparecieron mis iconos Nerd Font tras actualizar a macOS 26? El sistema vino con una nueva fuente por defecto en el terminal que no incluye glifos de Nerd Font. Reinstala una Nerd Font (FiraCode, JetBrainsMono, Hack) y selecciónala otra vez en las preferencias de Terminal.app o iTerm2. Starship no cambia entre versiones de macOS — siempre es un problema del lado de la fuente.
Q. ¿Está Starship escrito en Rust porque tiene que estarlo?
Sí, en la práctica. Un prompt corre en cada comando del shell, así que el coste de pausas de GC, fork-exec o startup del intérprete se acumula. Starship necesita leer tu .git/HEAD, parsear package.json, comprobar el contexto de Kubernetes y renderizar — todo en milisegundos de un solo dígito. Rust te lo da gratis sin runtime, igual que los demás CLIs en Rust de esta serie. Go también funcionaría, pero las cadenas de iteradores zero-cost de Rust y la ausencia de pausas de GC obligatorias dejan la latencia del peor caso más ajustada.
Conclusión
Starship es el prompt de configuración única que sobrevive a cada cambio de shell y a cada migración de máquina. Las cuatro cosas que recordar después de leer este artículo:
- Instala una vez, configura una vez.
curl -sS https://starship.rs/install.sh | sh, una líneaeval, un~/.config/starship.toml. - Empieza con un preset. Ejecuta
starship preset tokyo-night -o ~/.config/starship.tomly modifícalo desde ahí. No escribas la config desde cero a menos que disfrutes haciéndolo. - Usa paletas para los temas. Define los colores una vez en
[palettes.NOMBRE], úsalos desde todos los módulos y cambia la paleta activa con una sola línea. - Lanza
starship timingscuando el prompt se ralentice. Apunta directamente al módulo lento.
Starship encaja de forma natural con el resto de la serie de CLI moderna: bat para ver archivos con resaltado de sintaxis, delta para diffs, ripgrep para buscar, fzf para fuzzy finding, gh CLI para trabajar con GitHub, y Starship como el prompt que une todo. Mira la guía de dotfiles para versionar starship.toml correctamente junto a tu shell, y por qué los CLIs de Rust son tan rápidos para la historia técnica detrás del rendimiento que acabas de heredar.