Skip to content

ADR-0002: Zero Runtime Dependencies

  • Status: Accepted
  • Date: 2026-04-14
  • Supersedes: None
  • Amendment: ADR-0006 permits yaml@^2.8 as a narrowly-scoped runtime dependency (2026-04-15).
  • Amendment: ADR-0014 permits @huggingface/transformers and usearch under optionalDependencies for the opt-in Vector-Memory layer (2026-05-08).

Context and Problem Statement

package.json's dependencies block is the only way nubos-pilot can ship transitive complexity to end users through npx. Every runtime dependency carries three costs: a supply-chain surface, a version-compatibility constraint, and an install-failure mode (Windows path quirks, corporate proxies, air-gapped networks, peer-dep conflicts, abandoned maintainers). The question: should nubos-pilot ever declare runtime dependencies?

Scope

This ADR is about package.json.dependencies specifically: the subset of package.json that ships to end users via npm install / npx.

  • "Zero runtime deps" means: package.json.dependencies === {} (empty object, not absent). No library is pulled down at install time on an end-user machine.
  • devDependencies are explicitly permitted. Test runners, optional hook bundlers, and similar authoring-time tooling live there. They are never shipped to end users.
  • Environment assumptions are not dependencies. git, node >=22, and the host agent CLI are assumed to exist on the user's machine. They are prerequisites, not things nubos-pilot ships.

Decision Drivers

  • Sufficiency of Node builtins: the full markdown-workflow surface (frontmatter parsing, readline prompts, file locking, ANSI output, child-process spawn) is reachable through fs, path, os, child_process, readline, crypto, and util alone.
  • npx install reliability: zero deps ≈ zero failure modes on Windows, corporate networks, and air-gapped environments.
  • Patchability (Core Value): users copy .cjs files verbatim into .claude/nubos-pilot/ and sometimes patch them locally; there is no node_modules/ tree to keep in sync.
  • Security: zero runtime deps ≈ zero supply-chain surface.

Considered Options

  • Zero runtime dependencies: Node builtins + hand-rolled helpers. (CHOSEN)
  • Rich dependency tree: adopt a broad runtime surface (coding-agent SDK, playwright, sharp, chokidar, @modelcontextprotocol/sdk, chalk/picocolors).
  • Native Rust N-API engine: publish per-platform prebuilt binaries as optionalDependencies.
  • Accept a single narrow dependency pragmatically: e.g. yaml for frontmatter parsing.

Decision Outcome

Chosen: "Zero runtime dependencies", because it is the only option that reinforces the Core-Value patchability story and minimizes install-failure modes on the weakest user environments simultaneously. The devDependencies escape hatch covers authoring-time needs without leaking into end-user installs.

Escape hatch for future exceptions: if a concrete future feature genuinely requires a runtime dep that builtins cannot satisfy, the exception is introduced by a new ADR that either supersedes ADR-0002 wholesale or amends it narrowly with a name-scoped exemption. The escape is deliberately bureaucratic so that "just add a dep" never becomes the reflex answer. (See ADR-0006 for the first exercise of this hatch.)

Consequences

  • Good: npm install is effectively a no-op for end users.
  • Good: supply-chain audits are trivial.
  • Good: users can copy-patch .cjs files without module-resolution confusion.
  • Good: the install-payload tree contains only .cjs files and Markdown.
  • Bad: we reimplement small utilities (YAML frontmatter via hand-rolled parser, readline prompts, raw ANSI escapes). Accepted cost.
  • Neutral: devDependencies are permitted and do not ship to users.
  • Neutral: optionalDependencies for native prebuilt binaries is rejected as a general escape hatch by this ADR, so there is no accidental backdoor. The narrow exemption permitted by ADR-0014 is opt-in (config-gated, memory.enabled=true), lazy-loaded, and only resolves at install time when explicitly requested via npm install --include=optional.

Pros and Cons of the Options

Zero runtime dependencies — chosen

  • Good: Node builtins cover the entire markdown-workflow surface.
  • Good: preserves the Core Value "markdown-only, multi-runtime, ohne eigenes Daemon".
  • Bad: every small utility must be hand-rolled. Accepted.

Rich dependency tree — rejected

  • Good: chalk/picocolors produce nicer output; @clack/prompts produces nicer Q&A flows.
  • Bad: playwright, sharp, sql.js, chokidar, image addons target features we do not implement.
  • Bad: @modelcontextprotocol/sdk as a runtime dep contradicts REQUIREMENTS.md §"Out of Scope".
  • Bad: @anthropic-ai/claude-agent-sdk implies we spawn agents, which is the daemon pattern ADR-0001 forbids.
  • Bad: every transitive node_module is an install-failure risk on the environments that most need nubos-pilot to "just work".

Native Rust N-API engine — rejected

  • Good: native binaries offer raw-speed grep/ast-grep/syntax-highlighting.
  • Bad: requires per-platform prebuilt binaries with the associated CI/release plumbing.
  • Bad: we have no TUI, no image pipeline, no watcher.
  • Bad: Claude Code already exposes Grep, Read, Bash as first-class tools.
  • Bad: introducing a binary-ship story violates patchability.

Accept a single narrow dependency pragmatically — rejected (for now)

  • Good: one dep would make frontmatter parsing handle multiline sequences and anchors.
  • Bad: "just one dep" is a slippery slope.
  • Bad: the escape-hatch route exists for exactly this situation.

(Update: see ADR-0006; yaml@^2.8 was eventually accepted under the escape-hatch route.)

More Information

  • Related ADR: ADR-0005. The install-payload tree contains only .cjs + Markdown.
  • CLAUDE.md: §"Technology Stack" → "Installation"; §"External runtime dependencies"; §"Alternatives Considered".
  • REQUIREMENTS.md: §"Out of Scope" → "Nubos-MCP als First-Class-Dependency".

This ADR does not describe CI enforcement. CI-gate enforcement of the zero-deps rule is deferred to a later deploy/CI phase per ROADMAP.md; current enforcement consists of human PR review and this ADR as the authoritative reference.