0
0
NodejsComparisonBeginner · 4 min read

Package.json vs package-lock.json in Node.js: Key Differences and Usage

package.json lists your project's direct dependencies and metadata, while package-lock.json locks the exact versions of all installed packages including nested ones to ensure consistent installs.
⚖️

Quick Comparison

This table summarizes the main differences between package.json and package-lock.json in Node.js projects.

Aspectpackage.jsonpackage-lock.json
PurposeLists direct dependencies and project infoLocks exact versions of all installed packages
ContentDependency names with version rangesFull dependency tree with exact versions and resolved URLs
Created/UpdatedManually or via npm commandsAutomatically generated/updated by npm
Human readabilityEasily readable and editableMore detailed and less human-friendly
Version controlAlways committed to repoShould be committed to ensure consistent installs
Effect on installDefines what to installEnsures exact versions are installed
⚖️

Key Differences

package.json is the main file where you declare your project's metadata like name, version, scripts, and most importantly, the direct dependencies your project needs. It uses version ranges (like ^1.2.3) to specify acceptable versions, allowing flexibility when installing packages.

On the other hand, package-lock.json is automatically created by npm when you install packages. It records the exact versions of every package installed, including nested dependencies, along with their resolved URLs and integrity hashes. This file ensures that every time someone installs your project dependencies, they get the exact same versions, preventing unexpected bugs from version changes.

While package.json is meant to be human-readable and editable, package-lock.json is more detailed and not usually edited manually. Both files should be committed to version control to maintain consistency across different environments.

💻

package.json Example

json
{
  "name": "my-app",
  "version": "1.0.0",
  "scripts": {
    "start": "node index.js"
  },
  "dependencies": {
    "express": "^4.18.2"
  }
}
↔️

package-lock.json Equivalent

json
{
  "name": "my-app",
  "version": "1.0.0",
  "lockfileVersion": 2,
  "requires": true,
  "packages": {
    "": {
      "name": "my-app",
      "version": "1.0.0",
      "dependencies": {
        "express": "4.18.2"
      }
    },
    "node_modules/express": {
      "version": "4.18.2",
      "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
      "integrity": "sha512-...",
      "dependencies": {
        "accepts": "~1.3.8"
      }
    }
  },
  "dependencies": {
    "express": {
      "version": "4.18.2",
      "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
      "integrity": "sha512-...",
      "requires": {
        "accepts": "~1.3.8"
      }
    }
  }
}
🎯

When to Use Which

Choose package.json to define your project's direct dependencies, scripts, and metadata. It is the file you edit to add or update packages.

Always commit package-lock.json to your repository to lock down the exact versions of all dependencies and ensure consistent installs across all environments and team members.

In summary, package.json is for declaring what you want, and package-lock.json is for locking what you actually get.

Key Takeaways

package.json lists your project's direct dependencies with version ranges and metadata.
package-lock.json locks exact versions of all installed packages including nested dependencies.
Always commit both files to version control for consistent and reliable dependency management.
package.json is manually edited; package-lock.json is auto-generated by npm.
Use package.json to declare dependencies and package-lock.json to ensure exact installs.