package.json & npm — Alongside composer.json
debt(d3/e3/b5/t7)
Closest to 'default linter catches the common case' (d3). Detection hints cite npm-audit, snyk, and dependabot as automated tools that catch common mistakes like missing package-lock.json or using npm install in CI. These are standard ecosystem tools with automated detection capability, though they require explicit setup and don't catch silently.
Closest to 'simple parameterised fix' (e3). The quick_fix is explicit: 'Commit package-lock.json and use npm ci in CI.' This involves a one-file addition (package-lock.json) and a one-line substitution (npm install → npm ci), which is a small, localised remediation within the build configuration. No cross-cutting refactoring required.
Closest to 'persistent productivity tax' (b5). The term applies to contexts: web and cli, and affects any developer working with JavaScript dependencies in a PHP+JS hybrid project. The choice of dependency manager discipline (package-lock.json, npm ci vs install) influences build reproducibility, CI configuration, and onboarding patterns across the team. It's a recurring friction point but not architectural; many work streams touch dependency setup.
Closest to 'serious trap' (t7). The misconception field directly states the trap: 'npm install is safe in CI and production' — this contradicts the parallel discipline developers learn in PHP (composer.lock + composer install). The 'obvious' choice (npm install) is subtly wrong in CI contexts, violating the principle of least surprise when analogy to composer suggests equivalence. This is a documented gotcha that most developers eventually learn but often by incident in production.
Also Known As
TL;DR
Explanation
dependencies vs devDependencies: runtime JS deps vs build tools. scripts: run build tasks (npm run build, npm run dev). package-lock.json (or yarn.lock, pnpm-lock.yaml) pins exact versions — equivalent to composer.lock. Always commit the lock file. npm ci (not npm install) in CI for deterministic installs. Workspaces for monorepos. PHP projects typically have both composer.json (PHP deps) and package.json (JS deps) at the root.
Common Misconception
Why It Matters
Common Mistakes
- Not committing package-lock.json — same as not committing composer.lock
- npm install in CI instead of npm ci
- Committing node_modules — add to .gitignore like vendor/
- devDependencies in production image increasing attack surface
Code Examples
# Non-deterministic — may install different versions:
npm install
# node_modules committed to git (like committing vendor/)
# Deterministic from lock file (like composer install):
npm ci
# Dockerfile production — no devDependencies:
RUN npm ci --omit=dev
# .gitignore:
# node_modules/
# dist/ (built assets)
# .env (keep both .env.example files)