Manage Node.js dependencies
Dependencies are code you did not write, but run with your permissions and your data. A version that drifts between your machine and the platform is enough to create a bug you cannot reproduce. Keeping dependencies under control rests on three things: version ranges, the lockfile and tested updates.
Version ranges
In package.json:
{
"dependencies": {
"express": "^4.19.2",
"pg": "~8.11.5"
},
"devDependencies": {
"typescript": "5.5.4"
},
"engines": {
"node": ">=22"
}
}^4.19.2accepts minor and patch releases, not a major.~8.11.5accepts patches only.5.5.4pins an exact version.latestor*makes the deploy unreproducible.
dependencies is for runtime, devDependencies for build and test tools. A package used at startup but placed in devDependencies disappears with npm ci --omit=dev.
The lockfile is the contract
package-lock.json records the exact version tree. Commit it. npm ci installs that tree, deletes node_modules and fails when package.json and the lockfile disagree; it is the deploy command. npm install updates the lockfile and may change transitive versions.
Do not edit the lockfile by hand. If it is missing, generate it, test, then commit it. A lockfile generated on Windows remains valid on Linux, except for native modules.
Audit and update
npm outdated
npm audit
npm updatenpm outdated lists differences between installed, wanted and latest versions. npm audit reports known vulnerabilities; npm audit fix corrects within allowed ranges, while --force can break a major. Read the changelog before a major upgrade, update one package at a time and test startup plus a critical path.
Update bots (Dependabot, Renovate) reduce forgotten packages, provided you group patches and never merge without testing.
Native modules
sharp, bcrypt or canvas compile native code. They depend on the system C library and architecture. A prebuilt binary may not match the container, and you have no root to install build tools. Prefer a pure JavaScript alternative (bcryptjs), a version with prebuilds, or test the install on the platform before adopting it. A node-gyp error is an environment problem, not a syntax problem.
Check
After an update: npm ci, startup, health route, database access and log reading. Remove unused packages (npm ls helps spot duplicates). Keep the Node version declared in engines consistent with the selected runtime.
Advertisement
Was this article helpful?
Read next
- Connect Node.js to a databaseConfigure a MySQL or PostgreSQL pool from panel variables and handle migrations and backups.
- Node.js or Python for your project?Compare execution models and ecosystems to choose a runtime pragmatically.
- Deploy an Express APIStructure an Express API, validate input and expose a health route.