"name"stringPackage 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>`.
"name": "my-lib""name": "@myorg/utils"package.json field reference — 55+ fields explained with real examples, bilingual, searchable.
54 fields
"name"stringPackage 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>`.
"name": "my-lib""name": "@myorg/utils""version"stringSemantic 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.
"version": "1.0.0""version": "2.4.1""version": "0.0.1-alpha.1""description"stringOne-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.
"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.
"keywords": ["csv", "parser", "streaming", "tsv"]"homepage"stringURL of the project website or documentation. Shown as a link on the npm registry page.
"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`.
"bugs": "https://github.com/myorg/my-lib/issues""bugs": { "url": "https://github.com/myorg/my-lib/issues", "email": "bugs@example.com" }"license"stringSPDX 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.
Omitting `license` leaves it undefined — legally "all rights reserved". Set `"UNLICENSED"` explicitly for closed-source packages.
"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.
"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.
"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.
"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 } | ArrayFinancial support channels. npm shows a funding notice on install, and `npm fund` lists all packages with this field in your project.
"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"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.
"scripts": { "build": "tsc", "test": "vitest run", "lint": "eslint src" }"scripts": { "start": "node dist/index.js", "dev": "tsx watch src/index.ts" }"scripts.prepare"stringRuns before the package is packed or published, AND on local `npm install` (including git installs). Used to build output before publishing.
`prepare` also runs on local `npm install`, which can slow down installs for developers. For publish-only builds, use `prepublishOnly` instead.
"prepare": "npm run build""prepare": "husky install""scripts.prepublishOnly"stringRuns ONLY before `npm publish`, not on install. Safer than `prepare` for publish-specific checks like running tests before releasing.
"prepublishOnly": "npm test && npm run build""scripts.postinstall"stringRuns 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.
Run `npm install --ignore-scripts` in CI to skip all lifecycle scripts for security. You can then run only the ones you explicitly trust.
"postinstall": "node-gyp rebuild""postinstall": "node ./scripts/setup.js""scripts.pre<name> / post<name>"stringLifecycle 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`.
"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.
"config": { "port": "3000" }// in scripts: "start": "node server.js" // $npm_package_config_port is "3000""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.
"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.
TypeScript types for your library output should be in devDependencies, but the TypeScript package itself must be here too — not in dependencies.
"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.).
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.
"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.
"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.
"optionalDependencies": { "fsevents": "^2.3.0" }// in code: let fsevents; try { fsevents = require("fsevents"); } catch {}"bundleDependencies"string[] | booleanPackages bundled inside your tarball on publish. Useful when distributing a package that cannot rely on npm registry availability (offline deploys, vendor-locked packages).
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.
"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.
"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.
"resolutions": { "minimist": "^1.2.6", "**/lodash": "4.17.21" }"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.
`package.json`, `README`, `LICENSE`, and the `main` entry file are ALWAYS included regardless of `files`. You cannot exclude them.
"files": ["dist", "src", "!src/**/*.test.ts"]"files": ["lib", "types", "README.md"]"private"booleanPrevents accidental publishing. npm will refuse any `npm publish` command when this is `true`. Must-have in application repos and monorepo roots.
"private": true"publishConfig"objectConfig 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.
"publishConfig": { "access": "public" }"publishConfig": { "registry": "https://npm.mycompany.com", "tag": "next" }"main"stringLegacy 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`.
If you define `exports`, Node 12+ ignores `main` for routing. Keep `main` only as a fallback for very old tooling.
"main": "./dist/index.js""main": "lib/index.js""module"stringUnofficial 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.
"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.
"browser": "./dist/index.browser.js""browser": { "./lib/node-fs.js": "./lib/browser-fs.js", "./lib/net.js": false }"exports"string | objectExplicit 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.
Adding `exports` to an existing package is a BREAKING CHANGE — paths users imported directly (like `yourpkg/lib/utils`) stop working. Bump the major version.
"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.
"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.
"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.
"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.
"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.
CSS imports (`import "./styles.css"`) are side effects. `sideEffects: false` globally will drop your CSS. Use `"sideEffects": ["*.css", "*.scss"]` to protect them.
"sideEffects": false"sideEffects": ["*.css", "./src/polyfills.js"]"types" / "typings"stringPath 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`.
"types": "./dist/index.d.ts""typings": "types/index.d.ts""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.
"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).
"workspaces": { "packages": ["packages/*"], "nohoist": ["**/react-native", "**/react-native/**"] }"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.
"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.
"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.
"cpu": ["x64", "arm64"]"cpu": ["!ia32"]"packageManager"stringPin 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>`.
"packageManager": "pnpm@8.15.0""packageManager": "yarn@4.1.0"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.
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.
// bad: "peerDependencies": { "react": "*" }// good: "peerDependencies": { "react": "^17.0.0 || ^18.0.0" }"exports" blocks all unlisted sub-pathsOnce `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.
// before exports: import { helper } from "pkg/lib/helper" // worked// after exports (without listing ./lib/helper): same import THROWS"sideEffects: false" silently removes CSSIf your package has `import "./globals.css"` anywhere, setting `"sideEffects": false` causes Webpack/Vite to tree-shake it away. The CSS never loads.
// fix: "sideEffects": ["*.css", "*.scss", "./src/polyfills.js"]Forgetting "private": true in app reposWithout `"private": true`, a stray `npm publish` in an application repo publishes your entire app to the public registry — credentials, configs, and all.
"private": true // must-have in all app repos and monorepo root package.json"files" wins over .npmignoreIf 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.
"files": ["dist", "types"] // explicit allowlist beats any blacklistpeerDependencies are not auto-installednpm 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.
Include the full install command in your README: `npm install your-lib react react-dom`.
"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.
// npm / pnpm: "overrides": { "lodash": "4.17.21" }// yarn classic: "resolutions": { "**/lodash": "4.17.21" }Lock file must be committedAlways commit package-lock.json / yarn.lock / pnpm-lock.yaml. Without it, `npm install` may resolve different (possibly breaking) versions than what you tested.
# .gitignore: DO NOT add package-lock.json or yarn.lock or pnpm-lock.yaml"engines" is advisory by defaultnpm 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`.
# .npmrc: engine-strict=true"engines": { "node": ">=18.0.0" }React in "dependencies" of a component libraryPutting `react` in `dependencies` of a component library gives consumers two React instances — yours and theirs. This breaks hooks (useContext, useState) and causes cryptic errors.
Any package that must be a singleton in the host app — react, react-dom, vue, webpack, styled-components — belongs in `peerDependencies`, not `dependencies`.
// bad: "dependencies": { "react": "^18" } in a component library// good: "peerDependencies": { "react": "^18" }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.
Paste or drop your content into the tool panel.
Click the button. All processing is local in your browser.
Copy the result or download to disk in one click.
Use it in the small gaps between coding, reviewing, debugging, and shipping.
These links move the current task into a more complete workflow.
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.
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.
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.
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.
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.
Folks in your role tend to reach for these alongside this tool.