npm & Packages
Managing dependencies, scripts, and publishing packages — package.json, semver, npm vs pnpm vs Bun, lockfiles, and workspace patterns.
package.json is strict JSON, not JavaScript. A // comment or a trailing comma, both perfectly fine in a .js file, make it unreadable, and then every npm command in the project fails with EJSONPARSE, including npm install and npm run. The annotated examples on this page use // comments to explain each field, so copy the fields, not the comments.
{
"name": "my-app",
"version": "1.0.0",
"type": "module", // "module" for ESM
"scripts": {
"start": "node src/index.js",
"test": "node --test",
}
}
// $ npm run start
// npm error code EJSONPARSE
// npm error JSON.parse Invalid package.json: JSONParseError: Expected double-quoted property name in JSON at position 74 (line 4 column 31) ...
// npm error JSON.parse Note: package.json must be actual JSON, not just JavaScript.Managing project dependencies
Creating a new project
mkdir my-project && cd my-project
npm init -y # creates package.json with defaults
# or: pnpm init / bun initInstalling packages
# Install a runtime dependency:
npm install express
npm install zod dotenv
# Install a dev dependency (only for development, not production):
npm install -D vitest eslint typescript
# Install a specific version:
npm install react@18.2.0
# Install globally (for CLI tools):
npm install -g nodemon
# Better: use npx to run without global install:
npx vitest # downloads and runs vitest without installingpackage.json — what the fields mean
{
"name": "my-app",
"version": "1.0.0", // must follow semver
"type": "module", // "module" for ESM, omit for CommonJS
"scripts": {
"start": "node src/index.js",
"dev": "nodemon src/index.js", // run: npm run dev
"test": "vitest",
"build": "tsc"
},
"dependencies": {
"express": "^4.18.2" // runtime — needed in production
},
"devDependencies": {
"vitest": "^1.0.0", // dev only — not shipped to production
"typescript":"^5.3.0"
},
"engines": {
"node": ">=18.0.0" // minimum Node.js version
}
}Keep package.json to plain JSON: double-quoted keys and strings, no comments and no trailing commas. Let tools edit it for you where they can (npm install, npm pkg set), and if you need notes, put them in the README:
{
"name": "my-app",
"version": "1.0.0",
"type": "module",
"scripts": {
"start": "node src/index.js",
"test": "node --test"
}
}
// $ npm run start
// > node src/index.js
// app startedSemantic versioning (semver)
// Version format: MAJOR.MINOR.PATCH
// 1.2.3
// ↑ ↑ ↑
// │ │ └─ PATCH: bug fixes (backwards-compatible)
// │ └─── MINOR: new features (backwards-compatible)
// └───── MAJOR: breaking changes
// Semver ranges in package.json:
"express": "^4.18.2" // ^ = compatible: 4.18.2 to <5.0.0
"express": "~4.18.2" // ~ = patch only: 4.18.2 to <4.19.0
"express": "4.18.2" // exact version onlyOfficial Sources
- npm Documentation
- Node.js Docs — Packages and modules
- semver.org — Semantic Versioning
- pnpm Documentation
- Bun Documentation
The Codex links only to official documentation and the ECMAScript specification. No third-party tutorials.