What is NPM (Node Package Manager)?
In the previous article, we learned how to use NodeJS to run JavaScript on your computer. While this is useful already, NodeJS programs become even more powerful when you add another tool: NPM, or Node Package Manager. Luckily, NPM comes bundled with NodeJS, so once you’ve installed NodeJS, you can start using NPM as well.
NPM is a tool that builds upon NodeJS’s powers to help us reuse other people’s code in our projects, as well as share our own with the world. In this article, we’ll go into more detail about what NPM is and how it can be useful for you.
By the end, you’ll understand:
- How NPM can help you reuse existing code in your own programs
- How to explore the many code packages in the NPM package registry
- Package managers, and why they’re useful
- How to set up an NPM workflow
Learning about the broad concepts will increase your confidence—but if you’d like to see things in action first, skip to the exercise at the end (“Practice NPM: The Development Flow”). You can come back for all the what’s and why’s later.
Coding is a communal effort: we share code that makes our lives easier, and we openly provide solutions to problems others might have. For the sake of conveniency, developers often bundle such code and functions together in reusable units, known as code packages.
These code packages are then uploaded to package registries, a browsable index with thousands of solutions and code packages for all of us to exchange, borrow, and try out ourselves.
When you have so many packages to sift through, however, it can quickly get overwhelming. Fortunately, we have a helpful tool at our disposal: package managers to automatically download, install, and organize code packages for us.
NPM: Nodejs’s (Code) Package Registry and Manager
Section titled “NPM: Nodejs’s (Code) Package Registry and Manager”NPM is the standard package registry and manager for NodeJS. If we think of code packages as magic books of reusable incantations, then NPM is a library and the librarian for those books. As a library, the NPM registry is a catalog of code packages written and distributed by all sorts of developers for public use. And as a librarian, the NPM manager knows exactly how to fetch the packages we want and keep them updated, so we can focus on the fun part—the magic.
You might be wondering: how can NPM be both a library and a librarian? The secret is that NPM actually consists of two separate but connected parts:
- The NPM website is NodeJS’s package registry. It’s an online catalog of reusable code, where you can search through countless available packages, read their documentation, and even see their code in-browser.
- The NPM command line, which comes included with Node, is NodeJS’s package manager. It wrangles and delivers code packages from the package registry. Like asking a librarian for help finding a book, all you have to do is enter a command to download a package from the registry, and NPM will do the rest by installing it in your project.
What we can create with JavaScript—and NodeJS—is an endless world of possibilities. Similarly, code packages you can find in the NPM registry range from things like scripts that add special webpage effects, a CSS library for your UI, static website builders like Astro, and a whole lot more. If you ever find yourself wishing for a feature you don’t really know how to (or want to) make, search the NPM registry, because there’s a good chance it might already exist.
By using NPM, you’ll also have access to countless tools that can simplify and power-up your web development journey, whether it’s customizing your text editor or creating an entire website from scratch. No matter how much coding experience you have, introducing NPM into your workflow will speed up your learning process so you don’t get stuck on the little things.
As the largest and most popular collection of JavaScript code packages (and more! ), the NPM package registry gives you access to a wide ecosystem of programs and reusable code already written by other developers. Through the registry, you can find many different tools for your projects, codespace, and whatever else you might need in your workflow.
For example, some of my favorites are:
- Prettier, a formatter that cleans my code and makes it more readable;
- Sharp, a tool that compresses images and turns them into web-friendly reasonably-sized files;
- Chance, a random generator that can be used on both the command line and my websites.
Additionally, accessing a package registry allows you to review information about a program, in addition to downloading its files. So before installing a package, be sure to check out its:
- Documentation, sometimes also the README, which contains everything the developer wants you to know about the program: its purpose, intended use cases, how the code works, installation, additional options, and known issues. You should always review documentation before downloading anything, so you know what to expect.
- Reputation, since you’ll most often download code written and distributed by strangers. Anything you download from the internet has the potential to be unsafe, and while a good reputation doesn’t necessarily guarantee safety, popular packages from reputable sources are less likely to be malicious.
- Source and recent updates, so you can see where the code is coming from and if the developer is still working on it. You might determine a package’s source is safe if you trust the distributor or developer; if you reviewed the “Code” tab for anything suspicious; or if the package has an open source GitHub repository where you can see who built it as well as any recent updates. Though there is no perfect system that will promise usability, the more information you have access to, the better your judgment will be.
Now that you have some idea of what’s out there, try exploring the library at npmjs.com! You can also check out their guide and documentation on searching for packages.
(And if you’re really curious, here are the packages released by FujoCoded!)
Your Dependable Librarian: The NPM Package Manager
Section titled “Your Dependable Librarian: The NPM Package Manager”NPM is used as a package manager through the command line in order to download, install, and manage code packages as well as your projects in a variety of ways. With it, you can update installed packages, create personalized shortcuts, and even upload and share your own code, if you ever want to get more advanced.
NPM manages everything with package.json
, a file in the root
directory of your NPM project. Any code you’ve downloaded from the NPM
registry is automatically added into your project’s node_modules
folder. We’ll
learn more about this in the next article.
Though there are other package managers out there, we strongly recommend that
you stick with NPM until you gain more experience. Once you’re comfortable and
discover more resources, you might hear about other options such as yarn
,
pnpm
, deno
, and bun
. While they all have their differences, the concepts
you learn here are broadly applicable to most others.
Package managers exist in the first place to help developers build their projects more efficiently, regardless of a project’s complexity. Though everything a package manager does could be done by us humans, we’ll soon run into problems when new code gets added, packages get updated (a never-ending process), and especially when it comes to untangling dependencies.
Because coding is a communal effort, code packages often reference other code packages to use. This relationship between code packages is called a dependency. Much like how you can use NPM to reuse other people’s code, so do the code packages themselves. By using a package manager, your computer can sort out all the dependencies by looking at pre-existing registries and keeping your code updated. This will save you from many, many, many future headaches if you try to do it all yourself.
As your project grows, a package manager will keep your code up-to-date and maintain the stability of your project. Most code can be run regardless of package manager, so you’re not expected to rely on only one. If a specific package manager is required, the program’s README should tell you which one to use. However, we highly suggest for you to use NPM because of its popularity among developers, and therefore the amount of resources you’ll have access to.
While we’ll cover the depth of NPM in another article, you can start using NPM without fully understanding it. In fact, most people learn NPM this way: by jumping in and trying out some basic commands.
In this exercise, we’ll show you two examples of using NPM: with a starter project, and creating a project from scratch.
Let’s create an extremely simple NPM project! You’ll start most (if not all) projects this way. At the end, you’ll have created a program that can generate a random rainbow ASCII cat! V(=^・ω・^=)v
-
Create a folder for your project.
Terminal window mkdir npm-shenaniganscd npm-shenanigansCreate a folder on your computer for your project. Navigate into it with
cd
. -
Run
npm init
to initialize your project.After running this command, you will be prompted to fill-in some details about your project. NPM will set the text between parentheses
()
as your default values if a field is left empty.Terminal window npm initThis utility will walk you through creating a package.json file.It only covers the most common items, and tries to guess sensible defaults.See `npm help init` for definitive documentation on these fieldsand exactly what they do.Use `npm install <pkg>` afterwards to install a package andsave it as a dependency in the package.json file.Press ^C at any time to quit.package name: (npm-shenanigans) █Press enter as new prompts show up or type your own answers until you reach a final confirmation for the
package.json
file we’re about to create. Don’t worry too much about your answers at this stage, you can always edit them later! -
Confirm the creation of your
package.json
file.Terminal window npm initThis utility will walk you through creating a package.json file.It only covers the most common items, and tries to guess sensible defaults.See `npm help init` for definitive documentation on these fieldsand exactly what they do.Use `npm install <pkg>` afterwards to install a package andsave it as a dependency in the package.json file.Press ^C at any time to quit.package name: (npm-shenanigans)version: (1.0.0)description: A project to practice our NPM skills!entry point: (index.js)test command:git repository:keywords:author: boba-tanlicense: (ISC)About to write to /Users/boba-tan/npm-shenanigans/package.json:{"name": "npm-shenanigans","version": "1.0.0","description": "A project to practice our NPM skills!","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1"},"author": "boba-tan","license": "ISC"}Is this OK? (yes) █Type
yes
or press enter to confirm! Now that we’re done with ournpm init
command, a new file calledpackage.json
has been created.This command might also create a
package-lock.json
(which in practice you will never need to look at), and thenode_modules/
folder, which stores the downloaded and installed code for this project. Even if these two things aren’t created already, installing a library later will still automatically add these files and folders, so don’t worry if you’re only seeingpackage.json
for now.Directory/
DirectoryUsers/
Directoryboba-tan/
Directorynpm-shenanigans/
- package.json
-
Run
npm pkg set type=module
This will turn on modern JavaScript features that NPM doesn’t set up by default. Since many modern libraries rely on these newer features, you might run into errors if you forget this step.
If you don’t set the type now, NPM will error when it run and tell you to
set "type": "module" in the package.json
.Now, take a look, a new line has been automatically added to your
packacge.json
.package.json {"name": "npm-shenanigans","version": "1.0.0","description": "A project to practice our NPM skills!","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1"},"author": "boba-tan","license": "ISC","type": "module"} -
(Optional) Ignore the
node_modules/
folder when using git.If you use, or plan to use, git in your project, add a line for
node_modules/
to your.gitignore
file to keep your repository clean.The
node_modules/
folder is filled up using the information in thepackage.json
andpackage-lock.json
files, so you shouldn’t keep track of it in git.
-
Create a new file called
index.js
inside your project folder.Directory/
DirectoryUsers/
Directoryboba-tan/
Directorynpm-shenanigans/
- package.json
- index.js
Once you’ve created the file, open it in your text editor and add the following code to your file:
index.js console.log(":3c ~nyaa");Save the changes in your
index.js
file. -
Run your code with node.
In the command line, run
node index.js
.Terminal window node index.js:3c ~nyaa -
Run your code with an npm script.
Open you project’s
package.json
file in your text editor. Let’s take the command we used in the previous step and turn it into a script instead.In your
package.json
, look for the line that says"scripts":{}
. If you’ve been following closely, there’s probably a “test” script in there already with some messy code - feel free to ignore it. Let’s add a new script called “start” inside the curly brackets with our command from the previous step. Don’t forget to add commas between scripts!Your file should now look something like this:
package.json {"name": "npm-shenanigans","version": "1.0.0","description": "A project to practice our NPM skills!","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1""test": "echo \"Error: no test specified\" && exit 1","start": "node index.js"},"author": "boba-tan","license": "ISC","type": "module","dependencies": {}}Save the changes to your
package.json
file and run the start script we just defined.Terminal window npm run starttest-project@1.0.0 startnode index.js:3c ~nyaaAdding script commands in
package.json
will make your life much easier: you don’t need to remember the specific file names of every different file you want to run and it actually allows you to run multiple scripts at once as a single program. Script commands tend to have standard names likenpm run start
ornpm run dev
so they’re much easier to remember than individual file names.
For this exercise, we’re going to practice with Cat ASCII faces.
-
In the command line, run
npm install cat-ascii-faces
.Terminal window npm install cat-ascii-facesadded 8 packages, and audited 9 packages in 5sfound 0 vulnerabilitiesThe
npm install [package-name]
command adds a new package from npmjs.com to your project. To find the online home of a package you can type the name into the search or create the url yourself by adding/package/
and the package’s name, e.g.npmjs.com/package/cat-ascii-faces
.If it didn’t happen during the initialization step, then your
node_modules/
folder andpackage-lock.json
file should have been created.Directory/
DirectoryUsers/
Directoryboba-tan/
Directorynpm-shenanigans/
Directorynode_modules/
- cat-ascii-faces
- …
- package.json
- package-lock.json
- index.js
If you look at your
package.json
file, you’ll notice your new dependency has been added!package.json {"name": "npm-shenanigans","version": "1.0.0","description": "A project to practice our NPM skills!","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1","start": "node index.js"},"author": "boba-tan","license": "ISC","type": "module","dependencies": {"cat-ascii-faces": "^2.0.0"}} -
Edit your code to use our new dependency
In your
index.js
file, edit your code like this:index.js import getRandomCatFace from "cat-ascii-faces";console.log(":3c ~nyaa")console.log(getRandomCatFace());The first line in the code imports a specific function (
getRandomCatFace()
) from thecat-ascii-faces
npm package.In the other line we added, we’re calling the function we imported inside a
console.log()
to display a random ASCII cat face in our console.Save the changes in your
index.js
file. -
Run the
start
scriptBecause of the code we added to
index.js
in the previous step, using node to run this file will now output a random ASCII cat face to our console.Terminal window npm run start(.=^・ェ・^=)
Let’s get you familiar with NPM and code packages without needing to do any coding yourself. All you need is your command line and a bit of curiosity to check out how package files are organized.
-
Download an existing project from the web.
Go to GitHub or a similar site and find a project that already includes a
package.json
file. To find out how to get this project onto your own device see our guide on git clone. (TODO: add link)Here’s what your new cloned project’s folder might look like:
Directory/
- …
DirectoryUsers/
Directoryboba-tan/
Directorystarter-project/
Directoryimages/
- …
Directorytests/
- …
- README.md
- index.js
- index.html
- package.json
- LICENSE
-
Install the project’s dependencies.
In your terminal use the
cd
command to navigate into the project folder and runnpm install
to download the project’s dependencies.Terminal window cd starter-projectnpm installadded 176 packages, and audited 177 packages in 23s33 packages are looking for fundingrun `npm fund` for details2 low severity vulnerabilitiesSome issues need review, and may require choosinga different dependency.Run `npm audit` for details.Once
npm install
is done running (might take a while!) you’ll see a few differences in your project folder: a new file calledpackage-lock.json
and anode_modules/
folder.Directory/
- …
DirectoryUsers/
Directoryboba-tan/
Directorystarter-project/
Directorynode_modules/
- …
Directoryimages/
- …
Directorytests/
- …
- index.js
- README.md
- index.html
- package.json
- package-lock.json
- LICENSE
-
Check for existing scripts.
Find out what scripts are available in the project you cloned by looking at the script section of
package.json
. -
Choose a script to run.
Use the listed commands to run your code via your command line. Most often, you’ll find
npm run start
ornpm run dev
to run the main program itself. Depending on the project there might be other scripts likelint
ortest
. Run a few different ones and see if you can figure out what they do!<screenshot of command line>
-
Take a look at your
node_modules/
folder.You’ll notice there’s a lot of packages in there already! All the current dependencies for the project will have been automatically installed by
npm install
, which you ran during the initialization step. -
Add a new dependency.
If you want, you can add new dependencies to the project with
npm install [package-name]
ornpm i [package-name]
. When you install a new package there’s no need to re-runnpm install
.
Ok, You’ve Convinced Me to Use NPM. Now What?
Section titled “Ok, You’ve Convinced Me to Use NPM. Now What?”If you’ve taken a look at how you can use NPM with an existing project, try it out with a project from scratch!
Try running npm create astro@latest
and
check out this tutorial
to start building your very own Astro blog!
You can also:
- Learn more about
package.json
. - Install NVM and get started with your own NPM project.
in our upcoming articles!