Architecture¶
Overview¶
nvb is a pure bash tool with a layered architecture. Each layer has a single responsibility and communicates through function calls and global variables.
┌─────────────────────────────────────────┐
│ Shell Hook (zsh/bash) │
│ Triggers on directory change, evals │
│ output from nvb refresh │
├─────────────────────────────────────────┤
│ bin/nvb CLI │
│ Command dispatch: refresh, current, │
│ doctor, version, help │
├─────────────────────────────────────────┤
│ Core Modules │
│ │
│ detect.sh → Find version files │
│ parse.sh → Extract & normalize │
│ alias.sh → Resolve aliases via API │
│ resolve.sh → Apply priority rules │
│ cache.sh → Skip redundant switches │
│ manager.sh → Generate apply commands │
│ config.sh → Config file & CLI mgmt │
│ log.sh → Structured logging │
└─────────────────────────────────────────┘
Execution Flow¶
- Hook fires —
chpwd(zsh) orPROMPT_COMMAND(bash) triggers on directory change - Fast-path check — if
$PWDhasn't changed, return immediately (no fork) - Detection — walk directory tree upward looking for version files
- Parsing — extract version from the found file, normalize it
- Alias resolution — if the version is an alias (
lts/*,node), resolve via nodejs.org API - Priority resolution — select the highest-priority valid version
- Cache check — if
(cwd, version, source)matches cache, skip - Auto-install — if
NVB_AUTO_INSTALL=true, emit install command for missing versions - Manager command — generate eval-able command for the user's version manager
- Cache update — store new state
Key Design Decisions¶
eval-based hook pattern¶
nvb refresh outputs shell commands to stdout. The hook evals this output in the user's interactive shell. This is necessary because some version managers (notably nvm) are shell functions that only exist in the interactive session — a subprocess can't call them.
Manager-agnostic adapter pattern¶
Each version manager has three functions in manager.sh:
- Detection: is this manager available?
- Availability: can it be used?
- Apply: what command switches the version?
Adding a new manager means implementing these three functions.
No side effects¶
nvb never modifies project files and never writes to the repository directory. Auto-installation of Node versions is opt-in via NVB_AUTO_INSTALL. It only reads version files and outputs commands.
Module Reference¶
| Module | Key Function | Purpose |
|---|---|---|
detect.sh |
nvb_detect_file |
Walk tree upward to find a file |
parse.sh |
nvb_parse_file |
Dispatch to format-specific parser |
alias.sh |
nvb_resolve_alias |
Resolve alias to concrete version |
resolve.sh |
nvb_resolve_version |
Apply priority, set result globals |
cache.sh |
nvb_cache_is_current |
Check if switch is needed |
manager.sh |
nvb_adapter_apply_cmd |
Generate eval-able command |
config.sh |
nvb_config_load |
Load config file, manage settings |
log.sh |
nvb_log |
Log to stderr at configured level |