npm basics — package.json, dependencies, scripts, and reproducible installs
What npm does
npm coordinates packages for a Node.js project
Node.js runs JavaScript outside the browser. npm is a package manager distributed with Node.js, and the public npm registry is a service that publishes package metadata and archives. The npm command reads project metadata, resolves compatible package versions, downloads packages, and runs named project scripts.
These are separate layers. A Node.js version problem is not automatically an npm registry problem, and a package install can succeed while the application later fails because its runtime API is incompatible.
Project files
package.json declares intent; package-lock.json records a resolution
package.json describes the project, scripts, supported runtimes, and direct dependency ranges. package-lock.json records the exact dependency graph npm resolved, including transitive packages and integrity hashes. Commit both files for an application so collaborators and CI can reproduce the reviewed graph.
node_modules is an installed working directory derived from the manifest and lockfile. It is normally excluded from version control. Deleting it can clear a broken local installation, but it is a diagnostic reset rather than a substitute for fixing an invalid dependency declaration.
npm init -y
npm pkg get name version scripts
npm install
npm ls --depth=0
Dependency types
Declare packages according to who needs them and when
dependencies are required when the project runs. devDependencies support development, testing, or building. A peer dependency says that the consuming project must provide a compatible package, which allows plugins to share one host library instead of installing private copies.
Optional dependencies may fail to install without failing the whole installation. Platform-specific packages can also be skipped legitimately. Read the package documentation before moving a dependency between sections merely to silence a warning.
npm install express
npm install --save-dev vitest
npm pkg get dependencies devDependencies peerDependencies
Version ranges
Semantic versions describe compatibility expectations, not guarantees
A semantic version has major, minor, and patch numbers. A caret range such as ^2.3.1 normally permits later minor and patch releases before version 3. A tilde range such as ~2.3.1 normally permits later patch releases before 2.4. Exact versions permit only one published version.
The lockfile chooses exact versions inside those ranges. npm install may update the lockfile when declarations change; npm update deliberately searches for newer compatible versions. Review dependency and test changes rather than assuming every range-compatible release is behaviorally safe.
npm outdated
npm view package-name version
npm view package-name versions --json
Install workflows
Use npm install for development and npm ci for a locked build
npm install reconciles package.json, the lockfile, and the existing installation. npm ci requires the manifest and lockfile to agree, removes the existing node_modules, and installs the locked graph without rewriting it. That behavior makes npm ci the stronger default for continuous integration and deployment.
# Local dependency work
npm install
git diff -- package.json package-lock.json
# CI or clean verification
npm ci
npm test
Scripts
npm scripts provide project-local commands with local binaries on PATH
Scripts under package.json create a shared command interface for development, tests, builds, and maintenance. When npm runs a script, executables from node_modules/.bin are placed on PATH, so the project uses its pinned tool version without requiring a global installation.
Arguments after -- are forwarded to the underlying script. Lifecycle names such as pretest and posttest run automatically around the matching script, so inspect them when a command performs unexpected extra work.
npm run
npm run build
npm test -- --runInBand
npm pkg get scripts
Diagnose installs
Read the first dependency conflict and verify the active environment
Start with the Node.js and npm versions, registry, and project root. An ERESOLVE report describes packages that request incompatible peer ranges. ENOENT often identifies a missing path or manifest. A module-not-found error can occur at install time or runtime, so note which command produced it before clearing caches.
- Do not use
--forceor--legacy-peer-depsbefore understanding which peer ranges conflict. - Check whether the repository expects a particular Node.js version through
engines,.nvmrc, or tool configuration. - Compare manifest and lockfile changes after every dependency command.
- Use
npm cache verifybefore deleting the cache; cache corruption is less common than declaration or environment problems.
node --version
npm --version
npm config get registry
npm prefix
npm doctor
npm ls
Security and maintenance
Treat audit output as a dependency decision, not an automatic command
npm audit maps known advisories onto the installed dependency graph. Confirm whether the vulnerable code is reachable and whether an update changes major versions. Review the proposed lockfile diff and run the project test suite. Avoid npm audit fix --force unless the breaking upgrades have been evaluated.
npm audit
npm explain vulnerable-package
npm audit fix --dry-run
npm test
Related