Here's one of the best things about JavaScript: you almost never have to build everything yourself. Developers all over the world share useful code as packages, and you can use them in your own projects for free.
These packages live in the npm registry, which holds well over two million packages. It's the largest collection of reusable code for any programming language. Need to format dates? There's a package. Make colorful terminal output? Package. Build a web server, resize images, validate email addresses, generate fake test data? Package, package, package, package.
npm (originally short for "Node Package Manager") is also the name of the tool you use to install them. It comes free with Node.js. Check it's there:
npm --version
Starting a project: package.json
Every Node project has a package.json file in its main folder. It's like the project's ID card: its name, version, the packages it depends on, and handy shortcut commands. Create one by running this in a new, empty folder:
npm init -y
(The -y means "yes to all the default answers.") You'll get a package.json that looks something like this:
{
"name": "my-project",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
Add "type": "module", to it so you can use import and export.
Installing a package
Let's install a popular little package called Day.js, which makes working with dates much easier than the built-in Date object from Grade 13:
npm install dayjs
Three things happen:
- npm downloads the package into a folder called
node_modules. - It adds the package to a
"dependencies"section in yourpackage.json, like"dayjs": "^1.11.13"(your version number will probably be newer), so anyone else who gets your project knows it needs Day.js. - It creates a file called
package-lock.json, which records the exact version of every package installed, so everyone on your team gets identical versions.
Now you can import it, using just the package's name (no ./):
import dayjs from "dayjs";
const today = dayjs("2026-10-15");
const christmas = dayjs("2026-12-25");
console.log(today.format("dddd, D MMMM YYYY"));
console.log(`Days until Christmas: ${christmas.diff(today, "day")}`);
console.log(`One month from now: ${today.add(1, "month").format("DD/MM/YYYY")}`);
Output
Thursday, 15 October 2026 Days until Christmas: 71 One month from now: 15/11/2026
So much nicer than counting milliseconds!
Package versions use three numbers, like 1.11.13, called semantic versioning: MAJOR.MINOR.PATCH. A patch update (1.11.14) fixes bugs. A minor update (1.12.0) adds features without breaking anything. A major update (2.0.0) might break things that used to work. The ^ in "^1.11.13" tells npm: "any newer version is fine, as long as the major number stays at 1." That way you get bug fixes automatically, but not surprise breaking changes.
node_modules and sharing your project
The node_modules folder can get huge (packages often depend on other packages, which depend on other packages...). You never edit it, and you never share it. When someone else downloads your project, they just run:
npm install
and npm reads package.json and package-lock.json, and downloads everything they need. That's why, as you'll see shortly, developers tell Git to ignore the node_modules folder.
npm scripts
The "scripts" section of package.json lets you create shortcut commands for your project:
"scripts": {
"start": "node index.js",
"test": "node --test"
}
Now npm start runs your app, and npm test runs your tests. Every developer who opens your project knows exactly how to start it, without reading any instructions. (For script names other than start and test, use npm run name, like npm run build.)
Dev dependencies
Some packages are only needed while you're developing (like testing tools or code formatters), not when the app is actually running. Install those with --save-dev:
npm install --save-dev prettier
They go into a separate "devDependencies" section.
Anyone can publish a package to npm, including the occasional bad actor. Before installing a package, check that it's popular and actively maintained (look at its page on npmjs.com: weekly downloads, last publish date, and the GitHub link). Double-check the spelling of the name, too. Scammers sometimes publish packages with names one letter off from popular ones, hoping you'll make a typo. And don't install a package for something you could write in three lines yourself!