Modules and npm
npm dependencies and devDependencies
Learn the difference between npm dependencies and devDependencies, how the -D flag adds dev-only packages, and how --production skips them on deploy.
8 minute lesson
When you install an npm package using npm install <package-name>, npm records it as a dependency by default:
npm install fastify
Use -D, short for --save-dev, for a development dependency:
npm install -D eslint
The distinction is about when the installed application needs the package:
dependenciesare required when production code runsdevDependenciesare needed only to develop, test, lint, or build the project
A package imported by the running server belongs in dependencies. A test runner normally belongs in devDependencies. Build tools require judgment: if the deployment builds from source, the build stage needs them; a runtime image containing already-built output may not.
Both sections contain version ranges. The exact resolved tree belongs in package-lock.json, including development packages even when they are omitted from one install.
For a production-only install, current npm uses:
npm ci --omit=dev
The older --production option is still recognized, but --omit=dev states the intent directly. Omitted development packages remain represented in the lockfile; they are not physically installed in that node_modules tree.
Do not classify a dependency by package reputation. A compiler can be runtime-critical in one architecture and development-only in another. Start from the exact production command and ask whether it imports or executes the package.
Test the production artifact in a clean environment. A local machine can hide a mistake because a dev dependency or globally installed tool happens to be available.
Your action is to classify your project’s direct packages from its real start and build commands. Run a clean npm ci --omit=dev, start the production artifact, and move any missing runtime package to the correct section.
Lesson completed