Skip to main content

Dev dependencies separated

ab-002151 · code-quality-essentials.dependencies.dev-dependencies-separated
Severity: lowactive

Why it matters

Build tools, test frameworks, and type definitions in dependencies instead of devDependencies bloat production installs and Docker images with packages that serve no runtime purpose. ISO 25010:2011 §6.5.1 classifies this as a structural defect. More concretely: typescript in dependencies means your production Node.js server or serverless function installs the TypeScript compiler on every cold start — adding hundreds of milliseconds to deploy times and attack surface for a tool that is never invoked at runtime.

Severity rationale

Low because miscategorized dependencies bloat production artifacts and extend attack surface without causing functional failures, making it a hygiene issue rather than a security emergency.

Remediation

Move build-time packages to devDependencies. Common packages that belong there: typescript, all @types/*, test runners (jest, vitest), linters (eslint, biome), and formatters (prettier).

# Move typescript from dependencies to devDependencies
npm uninstall typescript
npm install -D typescript

# Move jest to devDependencies
npm uninstall jest @types/jest
npm install -D jest @types/jest ts-jest

Verify your production build still works after the move:

npm install --omit=dev
npm run build

Detection

  • ID: code-quality-essentials.dependencies.dev-dependencies-separated

  • Severity: low

  • What to look for: Inspect package.json dependencies and devDependencies. All build-time tools, test frameworks, type definitions, linters, formatters, and code generation utilities should live in devDependencies, not dependencies. Packages that belong in devDependencies: typescript, @types/*, test runners (jest, vitest, mocha), testing libraries (@testing-library/*, playwright, cypress), linters (eslint, biome), formatters (prettier), bundler plugins (vite-, rollup-, webpack-*), code generators (prisma CLI in some setups). Packages that correctly live in dependencies: your runtime framework (next, express, react), runtime validation libraries (zod), database clients, production utilities. A miscategorized typescript in dependencies bloats production deploys unnecessarily.

  • Pass criteria: Enumerate all relevant code locations. Build tools, test runners, type definitions (@types/*), linters, and formatters are all in devDependencies. Runtime dependencies are correctly in dependencies with at least 1 verified location.

  • Fail criteria: One or more build/dev tools found in dependencies instead of devDependencies.

  • Skip (N/A) when: Not a Node.js project.

  • Detail on fail: "Build-time packages found in 'dependencies': [list]. These should be in 'devDependencies' to avoid bloating production builds." (list specific packages)

  • Remediation: Move packages to the correct section:

    # Move typescript from dependencies to devDependencies
    npm uninstall typescript
    npm install -D typescript
    
    # Move jest to devDependencies
    npm uninstall jest @types/jest
    npm install -D jest @types/jest ts-jest
    

    Verify production install works cleanly:

    npm install --omit=dev
    npm run build
    

External references

Taxons

History