Learn everything you need to know about using NPM with your web apps

You’ve probably seen many NodeJS articles. You always use NPM to install this or that package, but they never ever talk about it.

This is true even for my own articles. We always take NPM for granted. Yet, what will you do if there was no NPM or no NPM registry?

You will have to write always everything yourself or you will have to go trough the Internet to eventually find something useful.

Even if you do find a module to help you, there will be no way to manage its version. The next time it is updated it might break your app and make it unusable.

What’s worse the modules on which you depend might have their own dependencies, which then they might break. These kind of problems are extremely difficult to fix.

But it doesn’t end here. Those additional dependencies might rely on packages that have different versions but are the same as a package on which you rely on.

It becomes a nightmare to manage.

That is the time when you realize that NPM might be the best thing from the NodeJS community.

It’s no wonder that it has been the most used package manager out there, not just for Node but for any programming language and platform.

It not only solves all problems with installing dependencies but it is providing an enormous list of readily available packages.

It also handles the correct versions and what is even more critical, the correct versions of the dependencies of your dependencies.

NPM is so good, that many package managers for other languages and platforms try to emulate it.

NPM actually consist of two things. The NPM command line tool, which you use with every project and the NPM registry which contains all publicly available modules and packages.

What is an NPM package?

An NPM module is a piece of code, which you can download with

$ npm install some-package

Then you can use it in your project

var useful_package = require('some-package')

Just two lines and you are ready! It is that simple!

Such a package can be just a simple one file with a few lines, or it may contain hundreds of files and tons of code.

The NPM Registry

The NPM Registry is the central repository where all publicly available modules are published by both individuals and organisations.

They range from small snippets of code to full blown SDK for some online service.

It is maintained by npm Inc, and they to a great job to keep it always online for all of us.

What happens after you install a package?

It depends on how you installed it. You can install a package either locally or globally.

$ npm install some-package

This command will install the some-package module in the local node_modules folder. So if you run the command /path/to/project it will be installed /path/to/project/node_modules.

You don’t need to create node_modules yourself.

All the code will be only inside this folder. Then when you use require('some-package') for your project at /path/to/project it will automatically know where to look at!

It is a simple convention, which works beautifully.

This is how you should install all your project dependencies, always locally, because this way they only affect your own project.

Global packages

However, sometimes you want a package to be installed globally. You mainly want that when a package contains a tool.

For example, you might use the excellent http-server for locally testing static pages.

You can install it globally

$ npm install http-server -g

And then automatically, you have available the http-server executable which you can run with from anywhere.

$ http-server

Listing your installed modules

Once you start installing new packages, you easily might forget what you already have.

$ npm list

This command will show everything installed in your local node_modules folder, including the dependencies of your project dependencies.

$ npm list -g

That command will show all globally installed packages and their dependencies.

How to always remember with package.json

We’ve talked about installing and checking what is installed, but a project needs more than that.

You not only need to install packages, because packages change from version to version. You need to have the correct versions to be sure that you project will always work.

This is where package.json comes in.

{
  "name": "delaygram",
  "version": "0.1.0",
  "description": "Share pictures slowly.",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "pictures",
    "express"
  ],
  "author": "Stefan Fidanov",
  "license": "MIT",
  "dependencies": {
    "body-parser": "^1.12.3",
    "express": "^4.12.3",
    "express-session": "^1.11.1",
    "jade": "^1.9.2",
    "mongodb": "^2.0.27",
  },
  "devDependencies": {
    "mocha": "^2.3.3",
    "mockery": "^1.4.0",
    "node-mocks-http": "^1.5.0",
    "should": "^7.1.1"
  }
}

This is an example of how your package.json may look like.

The most interesting part of it is the dependencies section.

It contains all of your project dependencies. It also contains their allowed versions, according to SemVer.

For example "mocha": "^2.3.3" means that we would accept any non-major but newer version than 2.3.3, which means all version of kind 2.x.x where x.x. is bigger than or equal to 3.3.

Another interesting field is devDependencies, which is here to contain all your dependencies which are not needed to run your project, but are required when you are developing it.

For example, you could put here packages related to testing like mocha and should.

Installing dependencies from package.json

This is one of the easiest things. You just go to your project folder where your package.json is stored and run the following:

$ npm install

and all of your dependencies will be installed. When you run

$ npm install --production

in this case devDependencies will not be installed.

However, in both cases all dependencies will be installed with versions according to what you’ve put in package.json, so that you project runs wihtout a hitch if you put in production tomorrow or in five years.

As a result every developer on your project will have the same stuff and it will work the same.

How do you create package.json?

Yeah, we’ve talked a lot about the package.json and NPM but how do you create it?

Just run the following in your project folder:

$ npm init

And you will be asked a few questions that will fill most of the fields from above, except the dependency fields.

Filling dependencies

Filling dependencies by hand is not awesome, and of course NPM has a very easy solution to that, too. When installing just add the --save flag like this:

$ npm install some-package --save

As a result some-package with an aprorpiate version will be put in the dependencies section, and also installed in the local node_modules folder.

If you instead replace --save with --save-dev the package will be put in the devDependencies section.

Let’s automate it

Let’s face it, you always want your packages and their appropriate versions to be part of the dependencies in package.json. So writing it everytime is not optimal.

Instead run the following command once and forever:

$ npm config set save true

Once you do it, you don’t need anymore the --save flag. Your dependencies will always be put in your package.json.

Uninstalling

Sometimes you will also want to remove a package

$ npm uninstall some-packge --save

or

$ npm uninstall some-packge -g

one of these commands will then help you.

What prevents different versions of the same package to clash?

So far you’ve been installing, uninstalling, saving packages to package.json.

Now, you’ve got all your dependencies under control. However, you probably realize that they depend also on other modules, which depend on even more, etc.

What does happen when your project depends on a module, and a depedency relies on the same module but on a different incompatible version?

Thanks to NPM, you don’t have to think about it. It handles all of these transparently for you and there is never a clash of versions. It will always work.

Let’s make it strict

In general npm packages follow SemVer, but sometimes they don’t. What’s more some apps need to have the absolute exact version every time in production.

Not only that, but package.json only list your own dependencies, and not the dependencies of your dependencies.

Their dependencies are stored in their own package.json files which you don’t have control over them, and they might be written badly. So badly, that a future version of one of their dependencies can bring your own app down.

For those cases you can run the following command:

$ npm shrinkwrap

It will generate an npm-shrinkwrap.json package which contains the exact versions of not only your own dependencies but also of their own dependencies and so on.

It contains your whole dependency tree, with an exact version of every package on which your app relies on directly or indirectly.

Next time you run npm install it will automatically use this new json file and will install the exact version of every package and its dependencies.

Best practices when working with dependencies

NPM makes it super easy to work with external packages. What’s more, the NPM registry has a module for almost anything you might think of.

Sometimes you might feel that it is almost like a Lego, where all is done, you just have to assemble the right parts.

Here is the catch, you have to assemble the right parts. You have to choose carefully, what you depend on.

The main best practices to follow are

  • Never depend on modules with just 2 or 3 functions.
  • If you can write it in less than an hour, don’t use an external dependency.

because

  • External dependencies might become incompatible
  • External dependencies might be removed from NPM

We’ve seen this happen before, and it has broken many perfectly written web apps.

So carefully select what you depend on.

Next

You know now how to use NPM and all the most useful commands. Your next step is to learn how to structure your projects and NPM is part of that.

We’ve discussed here mainly the usage of NPM as part of your web project, but you can also use it to publish your own NPM modules.

You can also get our super helpful NPM cheat sheet for developers. It has everything you might need so that you don’t need to remember it all. Checkout it out bellow.


Other articles that you may like

Did you like this article?

Please share it

We are Stefan Fidanov & Vasil Lyutskanov. We share actionable advice about development with Node, Express, React and other web & mobile technologies.

It is everything that we have learned from years of experience working with customers from all over the world on projects of all sizes.

Let's work together
© 2024 Terlici Ltd · Terms · Privacy