Packages 101
Tags: beginners, javascript, dependencies, tooling
Published: 2019-02-20 18:36:33

---
title: Packages 101
published: true
description: An introduction to packages/package management with npm
tags: beginners, javascript, dependencies, tooling
cover_image: https://thepracticaldev.s3.amazonaws.com/i/l9kgjx8lpc3s1j9fz8du.jpg
---

Many web development projects use different packages. You will often see people talk about packages -- installing them, which ones they like, which ones they don't, how their size compares to others', whether a certain package was useful, etc. Packages are closely related to dependencies -- things your code needs in order to work.

Dependency management can be *very* complex; we won't go over things like versioning, etc. Different people and teams use different package managers; here, we'll just be using `npm`, which is very common.

We won't make a real project, just go over the package management portion of it. If you want to try the commands yourself, you will need:

* [node and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)
* a terminal to run the commands in

## So what _are_ packages, anyway?

A _package_ is code you want to use in your own project that comes from somewhere else. They can be used either just for the developers -- such as a package that lets you write and run tests for your code -- or in the project itself, such as a library of functions to make it easier to talk to websockets, or a package that gives you pre-made CSS classes to use in your code. Using a package instead of writing it yourself can save you a lot of time, and also make things easier. For example, maybe you don't know (or care to!) how the websocket protocol works, you just want a tool that lets you use it a chat app. Frequently, packages are talked about as dependencies: things your code needs in order to function correctly.

A _package manager_ is a tool you can use to handle packages for you: usually that means you use it to add (install) new packages, remove (uninstall) them, find new ones, etc. [npm](https://docs.npmjs.com/) is a package manager. You _could_ just find the code somewhere online and put it in its own script file in your source folder instead of as a package -- but if that code changes, or gets updated, you have to go find it again, get the new code, put it in yourself ... assuming you even know the code you're using was updated at all.

A package manager like npm also helps you manage _which_ version you should install. It has a _registry_ of the packages, where it stores the packages, their versions, etc. npm's registry is at [npmjs.com](https://www.npmjs.com/). Usually it will also take care of installing any dependencies of the packages you've installed, so that they will work.

## Quick syntax notes

* `<package_name>`: the name of a _single_ package. The angle brackets (`<` and `>`) are a common way of showing that you should replace that whole term (`<package_name>`) with what you want it to be. Often, when you see angle brackets in documentation, it indicates that the value that goes there is required. **You do NOT use the `<` and `>` when you run the commands.** Examples:
    * `npm view <package_name>` => `npm view react` to view information about a package named `react`
    * `npm search <package_name>` => `npm search cool_new_package` to look for a package named `cool_new_package`
* `[list_of_packages...]`: a list of package names. The square brackets (`[` and `]` are a common way of showing that something should be a list with a varying number of things inside it. It could have one item or many items. When you see something with square brackets in documentation, that usually means it's optional. **You do NOT use the `[` and `]` when you run the commands.** For example, `npm install [list_of_packages...]` could be:
    * `npm install jest chalk request`: install three packages -- one named `jest`, one named `chalk`, and one named `request`
    * `npm install react`: install one package named `react`
    * `npm install`: install all of the packages listed in the `package.json` file
* an **option** is something like `--save-dev` or `--depth`: it's used to give the command itself more information, like arguments to a function. Often they have a short form and a long form; e.g., the option for saving something in `devDependencies` on an `npm` command is written as `--save-dev` or `-D`. Usually the long version has two dashes (`--save-dev`), whereas the short version usually as just one (`-D`). We'll use the long versions here (I do when I run them myself, honestly!) because they are easier to understand.

## Getting started

Before we can add packages to a project, we need a project to add them to!

Often, you'll be working on a project that already exists, so you won't need to do this, but it's good to know how. It's a great way to create a sandbox to try things in without worrying that you might do something wrong.

npm uses a file called `package.json` for getting information about your project, like what dependencies it has. While it contains a lot of other important information, today we'll just focus on what it does for packages (explained more when we address how to add them).

You can make a new project by creating a new folder, and from within that folder, running one of two commands, both of which result in npm making a `package.json` file for you.

* `npm init`: starts an interactive app that asks you some questions and then creates a `package.json` file for you
* `npm --yes init`: creates a default `package.json` file for you, and doesn't make you answer any questions or pick anything (usually this is what I do to get started, it's faster)

Don't worry if you change your mind about an option you picked, or if you decide you want to add something later; `package.json` is just a file, and you can edit it in a text editor afterwards if you like.

If you are using git in your project, **make sure you have `node_modules` added to your `.gitignore` file.** You can do that by adding it to the file in a text editor, or by running `echo 'node_modules' >> .gitignore` from the command line.

## Finding packages

The easiest way to find a package is probably to look at the [npm registry's site](http://www.npmjs.com) -- you can search for packages, see how many people have used it, etc., get an idea of how its documentation is, etc. There are a *lot* of packages available: for whatever you're looking for, there is almost certainly an existing package, if not many, that will do what you need. If you try one and you don't like it, or it's too hard to use, try looking for another!

When you're looking at different packages, it can be helpful to look at the package's Github; this can give you an idea of how active it is, how many issues there are, etc. A package that hasn't been updated in a while isn't necessarily bad or out-of-date -- it may not have _needed_ updates. Similarly, a package with a lot of issues on Github may have that many issues because it has a _lot_ of users; it doesn't mean the package is bad or poorly maintained.

There are also commands you can run to see a lot of the same information from the command-line
_(remember, don't use the `<` and `>` when you run these with real package names!)_:

* `npm search <package_name>`: look for all packages in the npm registry whose name matches `<package_name>`
* `npm view <package_name>`: view detailed information about a package, such as its versions, keyswords, description, its own dependencies, etc.

## Adding new packages to a project

When you install a package, npm gets the package and puts it into your `node_modules` folder, as well as anything else that package itself needs. npm uses your `package.json` file to know what packages (and which versions) to install, as well as a [lot of other things](https://docs.npmjs.com/files/package.json).

There are two main kinds of dependencies in your `package.json` folder: `dependencies` and `devDependencies`. (There are also other kinds, but we won't worry about them today.)

  * `dependencies` are packages your project needs in order to run. If you are using a package like `moment` to handle math involving dates in your project, that would be a package you should have in `dependencies`: it's required for your project to work.
  * `devDependencies` are packages you want but that your code itself doesn't need to run when it's finished. A tool like TypeScript or Babel that compiles your code is a good example of a common `devDependencies` package: you need it while you're working on the code, but your project _itself_ doesn't need it to run. Something like a testing tool, or a linter, are also good examples of what would belong in `devDependencies`.

To add a new package, you use the `npm install` command. npm will also add the package information to your `package.json` file as a dependency automatically.

_(Remember, don't use the `[` and `]` when you run these with real package names!)_

* `npm install --dry-run [list_of_packages...]`: do everything as if you were going to install these packages, short of _actually_ installing them.
* `npm install --save-dev [list_of_packages...]`: install these packages and add them to our `package.json` as `devDependencies`
* `npm install --save-prod [list_of_packages...]`: install these packages and add them to our `package.json` as `dependencies`
* `npm install --global [list_of_packages...]`: install these packages _globally_ -- if you do this from a project folder, these packages will **not be added** to your `package.json` files in the project. A good example of when you might want to use this is for a tool like `create-react-app` that helps you _start_ a new project: because you want it to _make_ the project, you don't want to install it locally _inside_ the project.

## Dealing with existing packages

If you've just cloned an existing project, the first thing you should do is run `npm install`.

Because `node_modules` folders get _very_ large very quickly, they are almost always excluded from version control like git. That means that when you clone down a project, any packages you need aren't there yet, and the code won't work.

Once you have packages in a project, you will sometimes need to remove or update them; it's good to also just peruse things every so often, make sure you don't have unnecessary packages left lying around, etc.

* `npm uninstall [list_of_packages...]`: remove the packages listed (can be just one package); this will remove them from your `package.json` file as well as from your `node_modules` directory.
* `npm list --depth 0`: view list of all packages installed at the top level; to view _all_ packages and all _their_ dependencies, you can do `npm list --depth 1000`
* `npm la --depth 0`: view list of all packages installed, along with their descriptions at the top level
* `npm outdated`: view packages which are behind the desired version

---

Remember that using tools is a skill, and it takes practice to get good at it; it might feel weird or seem silly, but it can be helpful to make and delete a dozen fake projects _just_ to practice setting them up, wrangling packages, etc.

There are a [*many* more commands](https://docs.npmjs.com/cli-documentation/), and a lot of different ways to use them; you can read more about them in the documentation for the npm, or by running `npm help <command>` to get information about that specific command.