Skip to content

This guide and website are in beta! Help us make them awesome with your feedback!

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:

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 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.

An NPM search for "chance random generator" showing the "chance" package. On the right is a download icon with a note "You can view how many times each package has been downloaded by the number here" indicating that it has been downloaded 6,747,229 times.

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.

The NPM page for the Chance package with several annotations indicating what different parts are. 

At the top is the name of the package folder and the date it was last updated. 

The main content is the readme.md document for the repository and is labelled "The readme is almost always the package's landing page on a registry." 

In the sidebar on the right the repository link is labelled "Check out the code source on GitHub (you can also use this tab)" and the weekly downloads number is labelled "You can see how frequently this package is downloaded here".

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!)

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

  1. Create a folder for your project.

    Terminal window
    mkdir npm-shenanigans
    cd npm-shenanigans

    Create a folder on your computer for your project. Navigate into it with cd.

  2. 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 init
    This 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 fields
    and exactly what they do.
    Use `npm install <pkg>` afterwards to install a package and
    save 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!

  3. Confirm the creation of your package.json file.

    Terminal window
    npm init
    This 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 fields
    and exactly what they do.
    Use `npm install <pkg>` afterwards to install a package and
    save 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-tan
    license: (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 our npm init command, a new file called package.json has been created.

    This command might also create a package-lock.json (which in practice you will never need to look at), and the node_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 seeing package.json for now.

    • Directory/
      • DirectoryUsers/
        • Directoryboba-tan/
          • Directorynpm-shenanigans/
            • package.json
  4. 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"
    }
  5. (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 the package.json and package-lock.json files, so you shouldn’t keep track of it in git.

  1. 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.

  2. Run your code with node.

    In the command line, run node index.js.

    Terminal window
    node index.js
    :3c ~nyaa
  3. 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 start
    test-project@1.0.0 start
    node index.js
    :3c ~nyaa

    Adding 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 like npm run start or npm 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.

  1. In the command line, run npm install cat-ascii-faces.

    Terminal window
    npm install cat-ascii-faces
    added 8 packages, and audited 9 packages in 5s
    found 0 vulnerabilities

    The 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 and package-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"
    }
    }
  2. 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 the cat-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.

  3. Run the start script

    Because 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
    (.=^・ェ・^=)

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!