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
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 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. Usually it will also take care of installing any dependencies of the packages you’ve installed, so that they will work.
Quick syntax notes
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.
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.
The easiest way to find a package is probably to look at the npm registry’s site — 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.
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. If you use one of the –save options, npm will also add the package information to your package.json file.
(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
npm la –depth 0: view list of all packages installed, along with their descriptions
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, 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.