How to Customize nvm Color Output with NVM_COLORS: A Technical Deep Dive

nvm implements color customization through the NVM_COLORS environment variable, which validates five single-character codes and translates them into ANSI escape sequences via the nvm_set_colors and nvm_print_color_code functions in nvm.sh.

The Node Version Manager (nvm) enhances terminal readability by color-coding output for commands like nvm ls and nvm install. For users who need to adapt nvm's appearance to different terminal themes or accessibility requirements, the project provides the NVM_COLORS environment variable. This article examines the complete implementation of this color system in the nvm-sh/nvm repository, tracing how custom palettes flow from environment variables to terminal output.

How NVM_COLORS Works Under the Hood

The color customization system resides entirely in nvm.sh and follows a strict validation and translation pipeline.

Terminal Capability Detection with nvm_has_colors

Before rendering any colors, nvm verifies that the terminal supports them. The nvm_has_colors function (lines 81-86 in nvm.sh) checks three conditions: it verifies that tput reports at least 8 available colors, confirms that stdout is a TTY, and ensures the user has not set NVM_NO_COLORS. If any check fails, nvm outputs plain text regardless of other settings.

Parsing the Color Palette via nvm_set_colors

When you export a custom NVM_COLORS value, the nvm_set_colors function (lines 1031-1052 in nvm.sh) validates the input strictly. The function requires exactly five characters, each belonging to the allowed set rRgGbBcCyYmMkKeW. Each position represents a specific category:

  1. First character: Installed versions
  2. Second character: LTS/system versions
  3. Third character: Current active version
  4. Fourth character: Not-installed versions
  5. Fifth character: Default alias

After validation, the function exports the palette as NVM_COLORS (lines 1049-1051), making it available for subsequent color lookups.

The Color Translation Pipeline

Retrieving and applying colors involves two coordinated functions. First, nvm_get_colors (lines 1056-1078 in nvm.sh) reads the palette from NVM_COLORS, defaulting to bygre if unset, and extracts the character at the requested index (1-5, or 6 for the system variant).

Next, nvm_print_color_code (lines 1092-1115) translates these single-character identifiers into ANSI escape sequences. The mapping follows this pattern:

  • r → 0;31m (red), R → 1;31m (bright red)
  • g → 0;32m (green), G → 1;32m (bright green)
  • b → 0;34m (blue), B → 1;34m (bright blue)
  • c → 0;36m (cyan), C → 1;36m (bright cyan)
  • y → 0;33m (yellow), Y → 1;33m (bright yellow)
  • m → 0;35m (magenta), M → 1;35m (bright magenta)
  • k → 0;30m (black), K → 1;30m (bright black/dark gray)
  • e/E → 0m (empty/reset)
  • w → 0;37m (white), W → 1;37m (bright white)

Invalid characters trigger an error message rather than rendering incorrectly.

Applying Colors to Terminal Output

The final step occurs in nvm_wrap_with_color_code (lines 1080-1089 in nvm.sh). This function receives an ANSI code and text fragment. If nvm_has_colors returns true, it wraps the text in \033[<code>m<text>\033[0m. Otherwise, it returns plain text. Throughout nvm's command implementations, higher-level helpers like nvm_echo_with_colors utilize this wrapping system to render status lines with the custom palette.

Configuring Your Custom Color Scheme

You can customize nvm's appearance by setting NVM_COLORS before sourcing nvm.

Using the Default Palette

If you do not set NVM_COLORS, nvm uses the default bygre palette:

nvm ls

This renders:

  • blue (0;34m): Installed versions
  • yellow (0;33m): LTS/system versions
  • green (0;32m): Current version
  • red (0;31m): Not-installed versions
  • empty (0m): Default alias

Setting a Custom Palette

Export your five-character code before loading nvm:


# Magenta-cyan-yellow-green-blue theme

export NVM_COLORS="McYgb"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

nvm ls  # Output now uses your custom colors

This configuration maps:

  • M (bright magenta): Installed versions
  • c (cyan): LTS/system versions
  • Y (bright yellow): Current version
  • g (green): Not-installed versions
  • b (blue): Default alias

Disabling Colors Entirely

To force plain text output regardless of terminal capabilities:

export NVM_NO_COLORS=--no-colors
nvm ls  # Uncolored text output

When NVM_NO_COLORS is set, nvm_has_colors returns false, causing nvm_wrap_with_color_code to skip ANSI wrapping.

Technical Implementation Details in nvm.sh

The color system is entirely self-contained within the main nvm.sh script:

  • Lines 81-86: nvm_has_colors checks tput colors, TTY status, and NVM_NO_COLORS
  • Lines 1031-1052: nvm_set_colors validates the five-character constraint and allowed character set rRgGbBcCyYmMkKeW
  • Lines 1049-1051: Export of validated NVM_COLORS variable
  • Lines 1056-1078: nvm_get_colors extracts specific palette indices with default fallback bygre
  • Lines 1080-1089: nvm_wrap_with_color_code applies ANSI sequences conditionally
  • Lines 1092-1115: nvm_print_color_code maps characters to ANSI codes (0;31m, 1;35m, etc.)

The test suite in update_test_mocks.sh (lines 29-32) validates this implementation by exercising custom palettes like NVM_COLORS=0ygre against nvm ls-remote.

Summary

  • nvm implements color customization through the NVM_COLORS environment variable, processed entirely within nvm.sh.
  • The nvm_set_colors function enforces a strict five-character format using only allowed identifiers from the set rRgGbBcCyYmMkKeW.
  • The default palette bygre maps to blue, yellow, green, red, and empty/white for the five output categories.
  • nvm_get_colors and nvm_print_color_code translate palette characters into ANSI escape sequences.
  • Users can disable colors entirely by setting NVM_NO_COLORS=--no-colors.

Frequently Asked Questions

What is the default value for NVM_COLORS?

The default palette is bygre, which corresponds to blue for installed versions, yellow for LTS/system versions, green for the current version, red for not-installed versions, and empty/reset for the default alias. This default is defined in the nvm_get_colors function in nvm.sh as the fallback when NVM_COLORS is unset.

Why does my NVM_COLORS setting show an error?

The nvm_set_colors function in nvm.sh performs strict validation on the NVM_COLORS variable. It requires exactly five characters, and each character must be from the allowed set rRgGbBcCyYmMkKeW. If you provide fewer or more than five characters, or include characters outside this set (such as hex codes or RGB values), nvm outputs an error and refuses to apply the custom palette.

How do I completely disable colored output in nvm?

Set the NVM_NO_COLORS environment variable to --no-colors before sourcing nvm. When this variable is present, the nvm_has_colors function returns false, which causes nvm_wrap_with_color_code to bypass ANSI escape sequence wrapping and output plain text regardless of terminal capabilities.

Can I use RGB or hex color codes with NVM_COLORS?

No, nvm only supports the predefined single-character identifiers in the set rRgGbBcCyYmMkKeW. Each character maps to a specific ANSI 16-color escape sequence defined in the nvm_print_color_code function in nvm.sh. The system does not support 256-color palette codes or true-color (24-bit) RGB hex values.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →