Learn more about Russian war crimes in Ukraine.

What is npm?

Recently I wrote about Node.js’s two module systems, the traditional CommonJS module system, and the newer ECMAScript module system. These module systems are related to, but distinct from, package systems. A module is a thing loaded and executed at runtime. A package is a thing downloaded at “install time”. Packages can provide modules. There is only one one package system for Node.js that’s worth mentioning: NPM. Let’s take a look.

The NPM docs have an excellent, succinct definition of a “package”:

Note that this definition does not mention “Node.js modules”. An NPM package can contain arbitrary stuff. For example, you can distribute CSS via NPM. Just throw it anywhere in the folder. The contents are limited only by the vague NPM terms of use.

Yes, you can npm install foo/bar/baz/, a directory that contains a package.json. The package.json just has to have name and version fields. This adds "packagename": "file:foo/bar/baz" to your dependencies, and creates node_modules/packagename as a symlink to it.

Yes, you can npm install tarball.tar.gz, a gzipped tarball containing a package.json. This adds "packagename": "file:tarball.tar.gz" to your dependencies, and unzips the gzipped tarball into node_modules/packagename.

Yes, you can npm install http://example.com/tarball.tar.gz. This adds "packagename": "http://example.com/tarball.tar.gz" to your dependencies, and unzips the gzipped tarball into node_modules/packagename.

Yes, you can npm install 'git://github.com/jameshfisher/lodash.git#jims-fork'. This adds "lodash": "git://github.com/jameshfisher/lodash.git#jims-fork" to your dependencies, checks out the specified commit, and copies it into node_modules/lodash. This could come in handy for maintaining your own fork of a package.

Onto more familiar territory. When we run npm install lodash@4.17.20, the 4.17.20 is a “version”. This identifier maps to the URL https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz, a raw URLs to a tarball hosted on the NPM registry. However, NPM adds "lodash": "^4.17.20" to your dependencies, rather than adding the raw URL. You can query the NPM API to get the URL with:

$ curl -s https://registry.npmjs.org/lodash | jq '.versions | .["4.17.20"].dist.tarball'
"https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz"

NPM has a separate thing called “tags” which uses the same syntax as versions. For example, npm install jquery@beta installs the beta tag. Currently, the beta tag maps to version 3.5.1. NPM puts "jquery": "^3.5.1" in your dependencies, so the fact that you installed a tag is lost. You can see the current tag-to-version mapping with:

$ curl -s https://registry.npmjs.org/jquery | jq '.["dist-tags"].beta'
"3.5.1"

When you run npm install jquery, this is equivalent to npm install jquery@latest. It puts "jquery": "^3.5.1" in your dependencies, and forgets that you just installed latest.

Next time, I’ll look at making an example package, publishing it, and showing it in use.

What can computers do? What are the limits of mathematics? And just how busy can a busy beaver be? This year, I’m writing Busy Beavers, a unique interactive book on computability theory. You and I will take a practical and modern approach to answering these questions — or at least learning why some questions are unanswerable!

It’s only $19, and you can get 50% off if you find the discount code ... Not quite. Hackers use the console!

After months of secret toil, I and Andrew Carr released Everyday Data Science, a unique interactive online course! You’ll make the perfect glass of lemonade using Thompson sampling. You’ll lose weight with differential equations. And you might just qualify for the Olympics with a bit of statistics!

It’s $29, but you can get 50% off if you find the discount code ... Not quite. Hackers use the console!

More by Jim

Tagged #programming, #javascript. All content copyright James Fisher 2020. This post is not associated with my employer. Found an error? Edit this page.