EPISODE 01 — OPERATION NODE_MODULES

dep-upsurgeon

Upgrade npm dependencies one-by-one — with install + validation after every change, automatic rollback on failure, and a graph-driven conflict report.

$npm install -g dep-up-surgeon

▸ framework-agnostic · peerDeps graph · node 20.17+ / 22.9+

Anime surgeon mascot holding an npm syringe
v1.6.6
NO PATIENTS HARMED ✦
ROLLBACK ✓
◉ ONE-BY-ONE UPGRADES✚ INSTALL + VALIDATE⟲ AUTO ROLLBACK◇ PEER-GRAPH BATCHING⚠ CONFLICT REPORTING☰ JSON REPORT★ INTERACTIVE MODE⛨ FRAMEWORK-AGNOSTIC◉ ONE-BY-ONE UPGRADES✚ INSTALL + VALIDATE⟲ AUTO ROLLBACK◇ PEER-GRAPH BATCHING⚠ CONFLICT REPORTING☰ JSON REPORT★ INTERACTIVE MODE⛨ FRAMEWORK-AGNOSTIC
// FILE 01 — LIVE DEMO

operation log

A real session: plan → install → validate → rollback on trouble. Hit refresh to replay the surgery.

REC ● LIVE OP
CRT-OS v1.6.6
/dev/tty1
▸ POWER▸ CONTRAST▸ V-HOLD
■ dep-up-surgeon
// FILE 02 — TOOLKIT

Sticker-pack features

Peel, slap onto your CI pipeline, press firmly. Everything below is already in the shipped binary — no plugins, no bolt-ons.

Surgical one-by-one

Every upgrade is its own operation: bump → npm install → validate. If a patch fails, the package.json is restored from backup. No mass updates, no mystery regressions.

/core/retryEngine.ts

Peer-graph batching

With --link-groups auto, the tool reads each package's published peerDependencies and builds a graph. Connected components become one batch → one write → one install → one validation.

/core/graph.ts

Generic conflict parser

A regex-based parser classifies peer mismatches, missing peers, engine bumps, and unresolved trees — from real npm output. Root-only mentions get filtered so your own app doesn't look like a conflict.

/core/conflictParser.ts

Safety-first rollback

Before the first change, package.json is copied to package.json.dep-up-surgeon.bak. Even when npm exits 0 but the log is full of conflicts, the bump is rolled back — unless you --force it.

safety rail

Fallback strategies

@latest first, then walk back: major-lines (default) tries the best stable per major; minor-lines steps by major.minor. ERR_REQUIRE_ESM halts further tries for that package. Set none to lock to @latest only.

--fallback-strategy

Interactive recovery

--interactive turns failures into choices: skip, retry, pin, or --force the batch. After the run, optionally bulk-add failed names to .dep-up-surgeonrc so the next run stays clean.

/cli/interactive.ts

Machine-readable report

--json emits a single JSON object: upgraded, skipped, failed, conflicts, unresolved, groups, ignored. Drop it straight into CI, a PR bot, or a dashboard.

--json

Framework-agnostic

No hardcoded React / Angular / Vue lists. Grouping and conflict handling come from registry metadata and parsed npm output. @types/* pairs stay with their runtime packages automatically.

zero stack lock-in
Chibi surgeon mascot holding a pkg floppy disk
✦ KAWAII MODE ✦
READY TO OPERATE
// FILE 03 — INSTALL

Scrub in,
let's operate.

Install globally or run locally after cloning. From your project root (where package.json lives), call the CLI — optionally with --dry-run first.

▸ 01 — global install
$npm install -g dep-up-surgeon
▸ 02 — plan only (no writes)
$dep-up-surgeon --dry-run --json
▸ 03 — real surgery
$dep-up-surgeon --link-groups auto --fallback-strategy major-lines
// .dep-up-surgeonrc
{
  "ignore": ["some-legacy-package"],
  "linkedGroups": [
    {
      "id": "my-batch",
      "packages": ["package-a", "package-b"]
    }
  ]
}
// FILE 04 — FLAG DOSSIER

Flag reference

The full control panel. Exit code 1 when any upgrade could not be kept (unless --force).

--dry-run
Resolve latest versions and print the plan. Does not touch package.json or run installs. Pairs beautifully with --json in CI.
--interactive
On failure, prompts for next steps. Single-package: continue / pin / retry. Linked-group: skip / retry / force / freeze. Optionally bulk-adds failed names to .dep-up-surgeonrc.
--forcesharp
Keep a bump even when validation fails, and skip rollback when structured conflicts appear after a successful exit code. Use with care.
--ignore<pkg,pkg,...>
Comma-separated package names to skip. Merged with the ignore list from .dep-up-surgeonrc.
--jsonci-ready
Machine-readable report to stdout: upgraded, skipped, failed, conflicts, unresolved, groups, ignored.
--fallback-strategy<major-lines | minor-lines | none>default: major-lines
After @latest fails: major-lines (default) walks back by major (9.x→8.x→…). minor-lines steps one major.minor at a time. ESM/CJS errors (ERR_REQUIRE_ESM) stop further fallbacks for that package. none only tries @latest.
--link-groups<auto | none>default: auto
auto (default) builds linked batches from the registry peer-graph + your linkedGroups config. none upgrades strictly one dependency per step.

▸ note — non-registry ranges (workspace:, link:, file:, git:) are skipped for upgrades