npm & package.json
npm is the default package manager for Node.js, and package.json is the manifest file at the root of every project that records its name, version, scripts, and the third-party dependencies npm installs.
Learn npm & package.json in our free Node.js course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Node.js course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
By the end of this lesson you'll create a package.json with a single command, install both runtime and development packages, understand semver ranges, and define npm scripts that turn long commands into short, memorable names.
What You'll Learn in This Lesson
1️⃣ Creating a Manifest with npm init
Every Node.js project starts with a package.json file. You could write it by hand, but npm will scaffold one for you. Running npm init asks a series of questions; adding the -y ("yes") flag accepts all the defaults instantly.
That file is the heart of your project. Here is an annotated example showing the fields you'll meet most often. The name , version , and main fields describe the package itself; scripts and the two dependency objects do the day-to-day work.
2️⃣ Installing Packages
The whole point of npm is reusing code other people wrote. The npm install command (short: npm i ) downloads a package and records it in your package.json . Where it gets recorded depends on the flag you use.
When npm writes a dependency, it usually adds a version range rather than a single exact version, so you can pick up small bug fixes automatically. Those ranges use semantic versioning ( MAJOR.MINOR.PATCH ) with two key symbols:
- • ^ (caret) — allow minor and patch updates, but not a new major version. ^4.18.2 means "anything from 4.18.2 up to (but not including) 5.0.0".
- • ~ (tilde) — allow only patch updates. ~4.18.2 means "anything from 4.18.2 up to (but not including) 4.19.0".
- • No symbol — pin the exact version. 4.18.2 means only 4.18.2, nothing else.
3️⃣ npm Scripts
Typing long commands gets old fast. The "scripts" object lets you give a command a short name, then run it with npm run <name> . This is how almost every Node project standardises how it's started, developed, and tested.
A few script names are special: start and test can be run without the word run . Every other script needs npm run in front of it.
Your turn. Fill in the three blanks marked ___ to build a working manifest, then save it as package.json and run npm start .
Mini-Challenge: Bootstrap a Project
No blanks this time — just a brief and an outline. Run the steps yourself in an empty folder and confirm the result against the expected file tree. This sequence is exactly how a real Node project begins.
Common Errors (and the fix)
- "ENOENT: no such file or directory, open '.../package.json'" — You ran an npm command in the wrong folder . npm looks for package.json in the current directory. cd into your project root (or run npm init -y first to create one).
- Committing node_modules to Git — Don't. It's huge and fully rebuildable. Add node_modules to your .gitignore and commit package-lock.json instead so installs stay reproducible.
- "Cannot find module '...'" after cloning — The repo doesn't ship node_modules. Run npm install to download everything listed in package.json before starting the app.
- Missing or wrong "main" field — If main points at a file that doesn't exist, require("your-pkg") fails. Set main to your real entry file (commonly index.js ).
- "EACCES: permission denied" on a global install — Don't fix it with sudo . Use a version manager like nvm so npm owns its own folders, or set a user-level global prefix.
- Version conflicts / "ERESOLVE unable to resolve dependency tree" — Two packages demand incompatible versions of a third. Read the message, align the versions, or as a last resort retry with npm install --legacy-peer-deps .
Pro Tips
- 💡 Use npm ci in CI/CD: it installs straight from package-lock.json for fast, exact, reproducible builds.
- 💡 Check what's outdated with npm outdated , and audit for known vulnerabilities with npm audit .
- 💡 Run a package without installing it using npx — for example npx create-react-app my-app .
📋 Quick Reference — npm Commands
Task
Command
Create a manifest
npm init -y
Install a dependency
npm install pkg
Install a dev dependency
npm i -D pkg
Install everything
npm install
Run a script
npm run name
Uninstall a package
npm uninstall pkg
Install globally
npm i -g pkg
Tip: the "scripts" object lives inside package.json as { "start": "node index.js" } .
Frequently Asked Questions
🎉 Lesson Complete!
- ✅ npm is Node's package manager; package.json is the project manifest
- ✅ npm init -y scaffolds a manifest with defaults
- ✅ npm install pkg adds runtime deps; npm i -D pkg adds dev deps
- ✅ Never commit node_modules ; do commit package-lock.json
- ✅ Semver: ^ allows minor+patch, ~ allows patch only
- ✅ "scripts" turn long commands into npm run name
- ✅ Next lesson: The Event Loop — how Node handles many tasks without blocking
Practice quiz
Which command creates a package.json with default values, no questions asked?
- npm init -y
- npm start
- npm new
- npm create
Answer: npm init -y. npm init -y answers yes to every prompt and writes a default package.json.
In semantic versioning, what does the format MAJOR.MINOR.PATCH mean for 1.4.2?
- year.month.day
- size.speed.fixes
- major=1, minor=4, patch=2
- patch.minor.major
Answer: major=1, minor=4, patch=2. 1.4.2 reads as MAJOR 1, MINOR 4, PATCH 2.
Which file lists the EXACT versions installed and SHOULD be committed?
- node_modules
- package-lock.json
- README.md
- .npmignore
Answer: package-lock.json. package-lock.json pins exact versions and belongs in version control.
Which folder holds the actual package code and should NEVER be committed?
- dist
- src
- lib
- node_modules
Answer: node_modules. node_modules holds installed code and is excluded from git.
What does the caret in "express": "^4.18.2" allow?
- Only the exact 4.18.2
- Minor and patch updates, up to <5.0.0
- Any version including 5.x
- Only major updates
Answer: Minor and patch updates, up to <5.0.0. Caret (^) permits minor and patch updates but not the next major.
What does the tilde in "dayjs": "~2.29.4" allow?
- Major updates only
- Any version at all
- Patch updates only, up to <2.30.0
- Nothing — it is exact
Answer: Patch updates only, up to <2.30.0. Tilde (~) permits only patch updates within the same minor version.
Which flag installs a package into devDependencies?
- --prod
- --global
- --exact
- --save-dev
Answer: --save-dev. npm install --save-dev (or -D) records the package under devDependencies.
Which command runs the script named "start" in package.json?
- npm start
- npm run-start
- npm exec start
- node start
Answer: npm start. start is special — npm start works without the word run.
How do you run a custom script named "dev"?
- npm dev
- npm run dev
- node dev
- npm exec dev
Answer: npm run dev. Every script other than start/test/etc. needs npm run <name>.
What does plain npm install (no package name) do in a cloned project?
- Deletes node_modules
- Publishes the package
- Updates npm itself
- Installs everything listed in package.json
Answer: Installs everything listed in package.json. Bare npm install installs all dependencies from package.json.
Continue this course
- Previous: Modules (CommonJS & ESM)
- Next: The Event Loop