Skip to main content

package.json Cheatsheet — 55+ Fields Explained with Examples

package.json field reference — 55+ fields explained with real examples, bilingual, searchable.

  • Runs locally
  • Category Developer & DevOps
  • Best for Formatting, validating, shrinking, or inspecting code-adjacent text.
Section:

54 fields

Basic info

"name"string

Package name — must be URL-safe, lowercase, no spaces. Hyphens and underscores are fine. Scoped packages use @scope/name format. This is the identifier users type in `npm install <name>`.

Examples
"name": "my-lib"
"name": "@myorg/utils"
"version"string

Semantic version — MAJOR.MINOR.PATCH. Required for publishing. Bump correctly: MAJOR for breaking changes, MINOR for new features, PATCH for bug fixes. Pre-release: 1.0.0-alpha.1.

Examples
"version": "1.0.0"
"version": "2.4.1"
"version": "0.0.1-alpha.1"
"description"string

One-line description shown in npm search results. Keep it factual and short — no marketing copy. Appears on the registry page and in `npm search` output.

Examples
"description": "Fast CSV parser for Node.js"
"keywords"string[]

Tags that improve discoverability in `npm search`. Think about what terms someone would search when they need what your package provides.

Examples
"keywords": ["csv", "parser", "streaming", "tsv"]
"homepage"string

URL of the project website or documentation. Shown as a link on the npm registry page.

Examples
"homepage": "https://github.com/myorg/my-lib#readme"
"bugs"string | { url?: string; email?: string }

Issue tracker URL and/or contact email for bug reports. npm surfaces this as the "Report a vulnerability" link. Can be a plain URL string or an object with `url` and `email`.

Examples
"bugs": "https://github.com/myorg/my-lib/issues"
"bugs": { "url": "https://github.com/myorg/my-lib/issues", "email": "bugs@example.com" }
"license"string

SPDX license identifier. Use "MIT", "ISC", "Apache-2.0", "GPL-3.0", etc. For proprietary/private packages use "UNLICENSED" to signal no public license is granted.

Pitfall

Omitting `license` leaves it undefined — legally "all rights reserved". Set `"UNLICENSED"` explicitly for closed-source packages.

Examples
"license": "MIT"
"license": "Apache-2.0"
"license": "UNLICENSED"
"author"string | { name: string; email?: string; url?: string }

Package author. Can be a "Name <email> (url)" shorthand string, or an object with `name`, `email`, and `url` keys.

Examples
"author": "Tanya Ivanova <t@example.com> (https://example.com)"
"author": { "name": "Tanya Ivanova", "email": "t@example.com" }
"contributors"Array<string | { name: string; email?: string }>

List of contributors in the same format as `author`. Optional — `git log` is the canonical source of contribution history.

Examples
"contributors": ["Alice <a@example.com>", "Bob <b@example.com>"]
"repository"string | { type: string; url: string; directory?: string }

Source code location. npm shows a "Repository" link on the package page and enables `npm repo` to open it in a browser. Add `directory` for monorepo packages.

Examples
"repository": { "type": "git", "url": "https://github.com/myorg/my-lib.git" }
"repository": "github:myorg/my-lib"
"repository": { "type": "git", "url": "https://github.com/myorg/mono.git", "directory": "packages/my-lib" }
"funding"string | { type: string; url: string } | Array

Financial support channels. npm shows a funding notice on install, and `npm fund` lists all packages with this field in your project.

Examples
"funding": "https://github.com/sponsors/myorg"
"funding": { "type": "opencollective", "url": "https://opencollective.com/babel" }
"funding": [{ "type": "github", "url": "https://github.com/sponsors/myorg" }, { "type": "patreon", "url": "https://www.patreon.com/myorg" }]

Scripts

"scripts"Record<string, string>

Shell commands run via `npm run <key>`. Keys `start`, `test`, `stop`, and `restart` can omit the `run` sub-command. All scripts get node_modules/.bin on PATH automatically.

Examples
"scripts": { "build": "tsc", "test": "vitest run", "lint": "eslint src" }
"scripts": { "start": "node dist/index.js", "dev": "tsx watch src/index.ts" }
"scripts.prepare"string

Runs before the package is packed or published, AND on local `npm install` (including git installs). Used to build output before publishing.

Pitfall

`prepare` also runs on local `npm install`, which can slow down installs for developers. For publish-only builds, use `prepublishOnly` instead.

Examples
"prepare": "npm run build"
"prepare": "husky install"
"scripts.prepublishOnly"string

Runs ONLY before `npm publish`, not on install. Safer than `prepare` for publish-specific checks like running tests before releasing.

Examples
"prepublishOnly": "npm test && npm run build"
"scripts.postinstall"string

Runs after the package is installed. Widely used by native addons to compile C++ bindings. Any package's postinstall script runs automatically — review what you install.

Pitfall

Run `npm install --ignore-scripts` in CI to skip all lifecycle scripts for security. You can then run only the ones you explicitly trust.

Examples
"postinstall": "node-gyp rebuild"
"postinstall": "node ./scripts/setup.js"
"scripts.pre<name> / post<name>"string

Lifecycle hooks that fire automatically before or after `npm run <name>`. Works for ANY custom script name, not just built-ins. e.g. `prebuild` runs before `build`.

Examples
"prebuild": "rm -rf dist"
"postbuild": "node ./scripts/post-build.js"
"pretest": "eslint src"
"config"Record<string, string>

Default values accessible inside npm scripts via the `npm_package_config_<key>` environment variable. Users can override with `npm config set <pkg-name>:<key> <val>` without editing package.json.

Examples
"config": { "port": "3000" }
// in scripts: "start": "node server.js" // $npm_package_config_port is "3000"

Dependencies

"dependencies"Record<string, string>

Runtime packages. Installed when your package is installed from npm. Use semver ranges: `^` for compatible updates within the same major, `~` for patch-only updates.

Examples
"dependencies": { "express": "^4.18.0", "lodash": "~4.17.21" }
"dependencies": { "react": "^18.0.0", "react-dom": "^18.0.0" }
"devDependencies"Record<string, string>

Packages needed only in development (bundlers, test runners, linters, type checkers). NOT installed when users install your package from npm.

Pitfall

TypeScript types for your library output should be in devDependencies, but the TypeScript package itself must be here too — not in dependencies.

Examples
"devDependencies": { "typescript": "^5.0.0", "vitest": "^1.0.0", "eslint": "^9.0.0" }
"peerDependencies"Record<string, string>

Packages consumers of your library must install themselves. Use for plugins, framework adapters, and libraries that must share an instance with the host app (react, webpack, etc.).

Pitfall

Peer dependencies are NOT installed automatically. npm 7+ warns but does not always install. Users who miss them get cryptic runtime errors, not clear install errors.

Examples
"peerDependencies": { "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0" }
"peerDependencies": { "webpack": ">=4.0.0" }
"peerDependenciesMeta"Record<string, { optional?: boolean }>

Metadata for each peer dependency entry. Set `{ "optional": true }` to suppress the missing-peer warning when that peer is not installed.

Examples
"peerDependenciesMeta": { "typescript": { "optional": true }, "sass": { "optional": true } }
"optionalDependencies"Record<string, string>

Packages npm tries to install but does not fail if they cannot be installed (e.g. native addons for optional features). Your code must handle their absence gracefully.

Examples
"optionalDependencies": { "fsevents": "^2.3.0" }
// in code: let fsevents; try { fsevents = require("fsevents"); } catch {}
"bundleDependencies"string[] | boolean

Packages bundled inside your tarball on publish. Useful when distributing a package that cannot rely on npm registry availability (offline deploys, vendor-locked packages).

Pitfall

Bundling increases tarball size significantly. Use only when you have a specific reason — offline deploy, a fork, or a package that must be self-contained.

Examples
"bundleDependencies": ["my-vendored-lib", "internal-tool"]
"overrides" (npm ≥8.3)Record<string, string | object>

Force all nested uses of a transitive dependency to a specific version. Useful for applying a security patch before the upstream maintainer publishes a fix.

Examples
"overrides": { "minimist": "^1.2.6" }
"overrides": { "react": "^18.0.0", "some-pkg": { "lodash": "4.17.21" } }
"resolutions" (Yarn)Record<string, string>

Yarn's equivalent of npm `overrides`. Forces a transitive dependency to a specific version. Yarn Classic and Yarn Berry support slightly different glob syntax.

Examples
"resolutions": { "minimist": "^1.2.6", "**/lodash": "4.17.21" }

Publishing

"files"string[]

Allowlist of files/directories included when you `npm publish`. Files NOT listed are excluded. Omitting this includes everything (minus .gitignore). Always prefer `files` over .npmignore.

Pitfall

`package.json`, `README`, `LICENSE`, and the `main` entry file are ALWAYS included regardless of `files`. You cannot exclude them.

Examples
"files": ["dist", "src", "!src/**/*.test.ts"]
"files": ["lib", "types", "README.md"]
"private"boolean

Prevents accidental publishing. npm will refuse any `npm publish` command when this is `true`. Must-have in application repos and monorepo roots.

Examples
"private": true
"publishConfig"object

Config values that only apply during `npm publish`. Common uses: point to a private registry, set the default dist-tag, or set `access` for scoped packages.

Examples
"publishConfig": { "access": "public" }
"publishConfig": { "registry": "https://npm.mycompany.com", "tag": "next" }

Module / entry

"main"string

Legacy CJS entry point. Returned when someone does `require("your-package")`. Still supported by old tools and Node < 12. When `exports` is defined, Node 12+ prefers it over `main`.

Pitfall

If you define `exports`, Node 12+ ignores `main` for routing. Keep `main` only as a fallback for very old tooling.

Examples
"main": "./dist/index.js"
"main": "lib/index.js"
"module"string

Unofficial but widely supported ESM entry for bundlers (Rollup, Webpack, Vite). They prefer this over `main` to enable tree-shaking. Node.js itself does NOT use this field.

Examples
"module": "./dist/index.esm.js"
"module": "esm/index.js"
"browser"string | Record<string, string | false>

Browser-specific alternative to `main`. Bundlers swap in this file when building for browser targets. Object form remaps specific files or sets them to `false` to exclude from bundles.

Examples
"browser": "./dist/index.browser.js"
"browser": { "./lib/node-fs.js": "./lib/browser-fs.js", "./lib/net.js": false }
"exports"string | object

Explicit package entry-point map. Defines exactly which sub-paths can be imported. Any unlisted path throws ERR_PACKAGE_PATH_NOT_EXPORTED, making internals truly private.

Pitfall

Adding `exports` to an existing package is a BREAKING CHANGE — paths users imported directly (like `yourpkg/lib/utils`) stop working. Bump the major version.

Examples
"exports": "./dist/index.js"
"exports": { ".": { "import": "./dist/index.mjs", "require": "./dist/index.cjs" }, "./utils": "./dist/utils.js" }
"exports" — conditional keysobject (within exports entry)

Named conditions inside an exports path: `"import"` for ESM import, `"require"` for CJS require(), `"browser"` for bundlers, `"types"` for TypeScript, `"default"` as the fallback.

Examples
"exports": { ".": { "import": "./dist/esm/index.js", "require": "./dist/cjs/index.js", "types": "./dist/index.d.ts", "default": "./dist/cjs/index.js" } }
"imports"Record<string, string | object>

Package self-import map. Allows your own files to use `import "#utils"` instead of deep relative paths like `../../utils`. Keys must start with `#`. Node 12.7+ only.

Examples
"imports": { "#utils": "./src/utils.js", "#db": { "node": "./src/db.node.js", "default": "./src/db.web.js" } }
"bin"string | Record<string, string>

CLI executables symlinked into node_modules/.bin on install (and into PATH for global installs). The target file must have a `#!/usr/bin/env node` shebang.

Examples
"bin": "./cli.js"
"bin": { "my-tool": "./bin/my-tool.js", "my-tool-alt": "./bin/alt.js" }
"type""module" | "commonjs"

How `.js` files are interpreted. `"module"` → ES Modules (`import`/`export`). `"commonjs"` (default) → CommonJS (`require`). Override per-file with `.mjs` or `.cjs` extensions.

Examples
"type": "module"
"type": "commonjs"
"sideEffects"boolean | string[]

`false` tells bundlers every file is pure — unused exports can be dropped (tree-shaking). An array whitelists specific files that DO have side effects.

Pitfall

CSS imports (`import "./styles.css"`) are side effects. `sideEffects: false` globally will drop your CSS. Use `"sideEffects": ["*.css", "*.scss"]` to protect them.

Examples
"sideEffects": false
"sideEffects": ["*.css", "./src/polyfills.js"]
"types" / "typings"string

Path to the TypeScript declaration file (.d.ts) for the package root. TypeScript checks this first when resolving types. For sub-paths, use the `"types"` condition inside `exports`.

Examples
"types": "./dist/index.d.ts"
"typings": "types/index.d.ts"

Workspaces

"workspaces"string[]

Glob patterns pointing to local packages in a monorepo. npm/Yarn/pnpm symlink them into node_modules so they can be imported by name. Requires `"private": true` in the root.

Examples
"workspaces": ["packages/*"]
"workspaces": ["apps/*", "packages/*", "!packages/internal"]
"workspaces.nohoist" (Yarn)string[]

Yarn-specific: prevents listed packages from being hoisted to the root node_modules. Used when a workspace package must have its own copy co-located (e.g. React Native).

Examples
"workspaces": { "packages": ["packages/*"], "nohoist": ["**/react-native", "**/react-native/**"] }

Engines & platform

"engines"Record<string, string>

Required Node.js (and npm/pnpm/yarn) version range. npm WARNS (not errors) if the engine doesn't match by default. Set `engine-strict=true` in `.npmrc` to make mismatches fatal.

Examples
"engines": { "node": ">=18.0.0" }
"engines": { "node": ">=16.0.0 <22", "npm": ">=8.0.0" }
"os"string[]

Restrict which operating systems can install this package. Values match `process.platform`: `"linux"`, `"darwin"` (macOS), `"win32"`. Prefix with `!` to exclude.

Examples
"os": ["linux", "darwin"]
"os": ["!win32"]
"cpu"string[]

Restrict which CPU architectures are supported. Values match `process.arch`: `"x64"`, `"arm64"`, `"ia32"`. Common for native addons that distribute prebuilt binaries.

Examples
"cpu": ["x64", "arm64"]
"cpu": ["!ia32"]
"packageManager"string

Pin which package manager and exact version the project expects. Corepack enforces this — running the wrong manager in the project throws an error. Format: `<name>@<semver>`.

Examples
"packageManager": "pnpm@8.15.0"
"packageManager": "yarn@4.1.0"

Common pitfalls

Star range (*) in peerDependencies

`"react": "*"` accepts ANY react version, including incompatible majors. Your library installs silently alongside React 1 or React 19. Specify a real range.

Pitfall

Use `"^17.0.0 || ^18.0.0"` to support two specific majors. The `||` union pattern is the correct way to declare multi-major peer support.

Examples
// bad: "peerDependencies": { "react": "*" }
// good: "peerDependencies": { "react": "^17.0.0 || ^18.0.0" }
"exports" blocks all unlisted sub-paths

Once `exports` is set, every path not listed throws `ERR_PACKAGE_PATH_NOT_EXPORTED`. Adding `exports` to an existing package is a BREAKING CHANGE even if you only add the root `"."` entry.

Examples
// before exports: import { helper } from "pkg/lib/helper" // worked
// after exports (without listing ./lib/helper): same import THROWS
"sideEffects: false" silently removes CSS

If your package has `import "./globals.css"` anywhere, setting `"sideEffects": false` causes Webpack/Vite to tree-shake it away. The CSS never loads.

Examples
// fix: "sideEffects": ["*.css", "*.scss", "./src/polyfills.js"]
Forgetting "private": true in app repos

Without `"private": true`, a stray `npm publish` in an application repo publishes your entire app to the public registry — credentials, configs, and all.

Examples
"private": true // must-have in all app repos and monorepo root package.json
"files" wins over .npmignore

If BOTH `files` and `.npmignore` exist, `.npmignore` is completely ignored. If neither exists, npm falls back to `.gitignore`. Always use `files` — it's explicit and version-controlled.

Examples
"files": ["dist", "types"] // explicit allowlist beats any blacklist
peerDependencies are not auto-installed

npm 7+ warns about missing peers but does not always install them. npm 3–6 never installed them. Users must install peers alongside your package. Document this in your README.

Pitfall

Include the full install command in your README: `npm install your-lib react react-dom`.

Examples
"peerDependencies": { "react": "^18.0.0" }
// consumer runs: npm install your-lib react
"overrides" (npm) vs "resolutions" (Yarn)

npm uses `overrides` (v8.3+), Yarn uses `resolutions`. They are NOT interchangeable. pnpm also uses `overrides`. Yarn Classic and Berry have different glob syntax for resolutions.

Examples
// npm / pnpm: "overrides": { "lodash": "4.17.21" }
// yarn classic: "resolutions": { "**/lodash": "4.17.21" }
Lock file must be committed

Always commit package-lock.json / yarn.lock / pnpm-lock.yaml. Without it, `npm install` may resolve different (possibly breaking) versions than what you tested.

Examples
# .gitignore: DO NOT add package-lock.json or yarn.lock or pnpm-lock.yaml
"engines" is advisory by default

npm only WARNS if the engine range doesn't match — it still proceeds. To make it a hard error, add `engine-strict=true` to `.npmrc` in the repo, or pass `--engine-strict`.

Examples
# .npmrc: engine-strict=true
"engines": { "node": ">=18.0.0" }
React in "dependencies" of a component library

Putting `react` in `dependencies` of a component library gives consumers two React instances — yours and theirs. This breaks hooks (useContext, useState) and causes cryptic errors.

Pitfall

Any package that must be a singleton in the host app — react, react-dom, vue, webpack, styled-components — belongs in `peerDependencies`, not `dependencies`.

Examples
// bad: "dependencies": { "react": "^18" } in a component library
// good: "peerDependencies": { "react": "^18" }

What this tool does

Searchable reference for every package.json field you encounter in daily Node.js and front-end work. 55+ fields across eight categories: Basic (name, version, description, keywords, license, author, contributors, homepage, bugs, repository, funding), Scripts (scripts lifecycle, pre/post hooks, config), Dependencies (dependencies, devDependencies, peerDependencies, peerDependenciesMeta, optionalDependencies, bundleDependencies, overrides, resolutions), Publishing (files, private, publishConfig), Module (main, module, browser, exports, exports conditions, imports, bin, type, sideEffects, types), Workspaces (workspaces, nohoist), Engines (engines, os, cpu, packageManager), and Pitfalls (star ranges in peerDependencies, exports blocking deep requires, sideEffects: false killing CSS, private: true safety, files vs .npmignore, peers not auto-installed, overrides vs resolutions, lock file policy, engines advisory-only, deps vs peer for framework libs). Each entry shows the JSON key, value type, a plain explanation of what it controls and when to set it, and 1–3 copy-ready examples. Search filters across field name, description, and examples; category chips narrow to a single section; one-click copy on every example. Pure client-side, no upload, no tracking.

Tool details

Input
Text + Structured content
The page exposes text boxes, numeric controls, file pickers, or structured inputs depending on the tool.
Output
Live result + Copy
The result area focuses on usable output, with copy, download, or preview actions when supported.
Privacy
Browser-side processing
The main tool logic does not call an external API, so inputs normally stay in the current tab.
Save / share
Shareable URL state
Key settings are encoded in the URL so another person can reopen the same setup.
Performance budget
Initial JS <= 36 KB
No WASM budget is declared, keeping the tool quick to open on mobile.
Best fit
Developer & DevOps · Developer
Category and role tags drive related tools, internal links, and quick fit checks.

How to use

  1. 1. Input

    Paste or drop your content into the tool panel.

  2. 2. Process

    Click the button. All processing is local in your browser.

  3. 3. Copy / Download

    Copy the result or download to disk in one click.

How package.json Cheatsheet fits into your work

Use it in the small gaps between coding, reviewing, debugging, and shipping.

Developer jobs

  • Formatting, validating, shrinking, or inspecting code-adjacent text.
  • Preparing snippets for documentation, tickets, commits, or handoff.
  • Checking a small payload quickly without switching tools.

Developer checks

  • Run irreversible transforms like minify or obfuscate on a copy.
  • Keep secrets out of pasted snippets unless the tool explicitly stays local.
  • Use your normal tests or linter before shipping transformed code.

Good next steps

These links move the current task into a more complete workflow.

  1. 1 npm / yarn / pnpm Cheatsheet npm / yarn / pnpm cheat sheet — 80+ commands across init, install, scripts, publish, with cross-tool comparison. Open
  2. 2 Bash Cheatsheet Bash cheat sheet — 100+ commands & idioms for variables, conditionals, loops, functions, pipes, traps, with real one-liners. Open
  3. 3 Git Cheatsheet Git command cheat sheet — searchable, with explanations, common mistakes, and real examples. Open

Real-world use cases

  • Debugging a "missing peer dependency" warning

    npm 7+ warns about every missing peer dependency on install. You open the cheatsheet, look up peerDependenciesMeta, and add `{ "optional": true }` next to the peer your plugin supports but doesn't require. The noisy warning disappears without affecting real consumers who need that peer.

  • Setting up a monorepo with workspaces

    You're splitting a project into packages/ and apps/. You look up "workspaces" to confirm the glob syntax, check that the root needs "private": true, and add "packageManager" to pin pnpm. Ten minutes later the workspace symlinks are live and `pnpm -r build` runs all packages.

  • Publishing a library for the first time

    You want to publish a utility library but need to know what's included in the tarball and how to mark the public API. The cheatsheet covers "files" (allowlist), "exports" (sub-path control), "sideEffects: false" (enable tree-shaking), and "publishConfig.access: public" for scoped packages. All four are filled correctly in one sitting.

Common pitfalls

  • Putting `react` in `dependencies` of a component library — users end up with two React instances, breaking hooks. Use `peerDependencies` instead.

  • Setting `sideEffects: false` when you import CSS or polyfills as side effects — bundlers will silently drop those files. Use `"sideEffects": ["*.css"]` to whitelist them.

  • Forgetting `"private": true` in application repos — a mistyped `npm publish` goes public immediately.

Privacy

Everything runs in your browser. The field list is a static in-memory array, and the search box, category chips, and copy buttons never make a network request. Nothing you type is logged or sent anywhere.

FAQ

Tool combos

Folks in your role tend to reach for these alongside this tool.

Made by Toolora · 100% client-side · Updated 2026-07-01