What is in package.json?
By FrontendPro Editorial Team Updated 9/26/2026
Answer
package.json describes a package: how it is identified, what it depends on, and how other code should load it.
{
"name": "my-lib",
"version": "1.2.0",
"type": "module",
"main": "./dist/index.cjs",
"exports": { ".": { "import": "./dist/index.js", "require": "./dist/index.cjs" } },
"files": ["dist"],
"scripts": { "build": "tsup", "test": "vitest" },
"dependencies": { "zod": "^3.23.0" },
"devDependencies": { "vitest": "^2.0.0" },
"peerDependencies": { "react": ">=18" },
"engines": { "node": ">=20" }
}
The fields that actually change behaviour
type—"module"makes.jsfiles ES modules; omit it and they are CommonJS. This single line causes most "cannot use import statement" errors.exports— the modern entry point map. It also blocks deep imports of files you did not list, which is how you keep internals private. It supersedesmain, thoughmainremains as a fallback for old tooling.files— what actually gets published. Without it, you may ship your entire source tree.sideEffects: false— tells bundlers your modules are safe to tree-shake.
The three dependency kinds
dependencies are needed at runtime and installed for consumers. devDependencies are build and test tooling, not installed transitively. peerDependencies say "the host app must provide this" — used by plugins and React component libraries so two copies of React never end up in one bundle.
Version ranges
^1.2.0 allows minor and patch updates, ~1.2.0 only patch, and an exact 1.2.0 pins it. The lockfile is what actually determines installed versions, so commit it — the range in package.json is a policy, the lockfile is the fact.
Metadata like description, keywords, license, repository and author does not affect builds but is what npm displays and what search relies on.
