📦developer
Everything in package.json Explained (The Fields You Skip Actually Matter)
package.json has dozens of fields. Most tutorials only cover name, version, and scripts. Here are the others that affect security, compatibility, and publish quality.
6 min readFebruary 10, 2026Updated March 14, 2026By FreeToolKit TeamFree to read
Frequently Asked Questions
What is the difference between dependencies, devDependencies, and peerDependencies?+
dependencies are packages required to run your application in production — Express, React, database clients. They're installed when someone runs npm install in your project. devDependencies are packages needed only during development and building — Jest, TypeScript, ESLint, Webpack. They're not installed when your package is installed as a dependency by another project (unless NODE_ENV=development). peerDependencies are packages your library requires the consumer to provide — a React component library listing react as a peer dependency means it will use whatever React version the consuming project has, rather than installing its own. This prevents duplicate React instances and version conflicts. peerDependencies are not automatically installed; they're declared requirements.
What does the 'main' vs 'exports' field do in package.json?+
main specifies the entry point when someone does require('your-package') in CommonJS. It's been the standard since Node.js began. exports is a newer, more powerful alternative that supports multiple entry points, ESM vs CJS distinction, and conditional exports based on environment. With exports, you can expose different files for Node vs browsers, restrict which internal files can be imported (preventing consumers from importing private internals), and define exports for both import (ESM) and require (CJS) formats. Modern packages targeting both Node and browsers should use exports; main is kept for backward compatibility with older Node versions and tools that don't yet support exports.
How do npm version ranges (^, ~, *) work?+
Exact version (1.2.3) installs only that version. Tilde (~1.2.3) allows patch updates: >=1.2.3 and <1.3.0. Caret (^1.2.3) allows minor and patch updates: >=1.2.3 and <2.0.0. This is npm's default when you run npm install --save. Asterisk (*) allows any version. The assumption behind caret: semver-compliant packages don't introduce breaking changes in minor versions, only in major versions. This assumption is frequently violated in practice, which is why package-lock.json exists — it pins exact versions so that npm install gives the same result every time, regardless of what new versions have been published.
🔧 Free Tools Used in This Guide
FT
FreeToolKit Team
FreeToolKit Team
We build free browser tools so you don't have to install anything.
Tags:
npmnodejspackage-jsonjavascriptdeveloper