What do you want to learn?
Skip to main content
by Joe Eames
This course will teach you how to use NPM for your projects and publish packages for others to use in their projects.
Start CourseBookmarkAdd to Channel
Table of contents
Hello, I'm Joe Eames. Welcome to Pluralsight's NPM Playbook course. I'm really excited to present this course to you. I've been doing open source web development for quite while now and one of the tools that has emerged as a lasting standard has been NPM. Is the package manager against which all other package managers are measured, so it's definitely a tool that any web developer or node developer needs to know. This course is a bit different from most of the courses on Pluralsight. Instead of a linear course where one clip follows the next, this course is presented more like a playbook. Each clip is for the most part is self-contained. When you want know how to do something specific with NPM, you can easily find the right clip just by looking at the name and then watch what you need. Of course, you can still watch the entire course end to end which will give you a comprehensive understanding of NPM. This course is organized into three different parts. We're going to start out by looking at the basics of NPM. This includes the basic commands but also the basic usage of NPM, the type of things that you will do when you are first starting out with it. After that we'll look at some advanced topics with NPM. These are topics that you probably won't use very often but they're still good to know about because under certain circumstances they can be very handy. Finally, we're going to talk about publishing your own package with NPM. Most of the time when we're using NPM we'll be building a product for users but occasionally we may want to build a product for other developers to consume and an easy way to do that is to publish that code through NPM so that other developers can easily add it to their own projects. This section will show you exactly how to do that and how to keep it up to date. Finally, I've created a course repository here on GitHub. You can see the URL here. Because open source development changes so fast, products can quickly become out of date. If that happens I'll note it here on this GitHub repository in the read me, not only what the problem is but how to work around it until a course update can be published. So, it's a good idea to check this repository right now and make sure that the course is up to date, and with that, we'll get started with our NPM playbook.
What Is a Package?
Typical NPM Usage
One of the common things that you'll use NPM for is to look at other people's sample or starter projects. When dealing with projects like this, there's a very typical flow that we'll go through. The first thing we'll do is we will clone the project using Git. Once we have the project cloned, we'll move into the directory and then we always install using NPM install. This will install any dependencies noted in the package.json file for that project. Now that we have everything installed we want to see it in action and we'll do that using the NPM start command. This is only going to work if the project that you downloaded has created a start script. To determine if a project does has a start script, you can just open up the package.json file. Here I'm showing the package.json file for this project, and you can see under the scripts section we have a start script and a test script. Let's run that start script. In this case this project starts up a server running on port 3000. Another typical thing that we want to do is run the test for the project and we can do that with NPM test. Again, this only works if the project has created a test script but if it does support tests, then there's a good chance that they did create a test script. Oftentimes we don't care if the tests are passing unless the download is specifically about testing, so frequently we will skip this step and that's the typical flow that we use when dealing with sample and starter projects.
Getting help with NPM is actually pretty cool. You have several options. Obviously with NPM just like most command line utilities you can do NPM -h and that will give you a list of the typical NPM commands and some minor information about them. You can also do NPM and then a command, for example, install and -h and that will give you more information about that specific command, usually just the different kinds of usage for that command but there is another option that's very cool which is NPM help and then the command. This will actually open up a browser to the official help page for that command on NPM. This not only gives you the syntax but also a lot more information because the help documents are a lot more complete than just the command line help that you can see. There is one other thing you can do with help that's very cool. Let's say for example that you want to remove packages that are not in your package.json file but you can't remember the command for that or you're reading somewhere about removing and you want to find that article. You can do NPM help -search and then type in a word or a list of words, so I'll put in remove and this will actually give us a list of all the different help topics on the official documentation that include that word. So, you can see down here on the fourth line NPM help prune. You'll also see the NPM API help command shown here. If we execute one of those, that will take us to the documentation for the API which is for using NPM programmatically. Usually that's not what we want. Usually we want the regular NPM help, so NPM help prune will then take us to the page that we want.
There's one specific help document that you should be aware of and you'll probably want to refer back to multiple times and that is right here, the miscellaneous config page. The reason for that is that if you scroll down on the page you'll come to a list of shorthand commands for NPM. This is really nice to refer to frequently so that you can learn and memorize the shorthand commands for the different longer commands in NPM and this doesn't actually list out all of the shorthand commands, it lists out all the shorthand for the flags but there other shorthands that aren't listed here, for example, NPM install can be shortened up to just NPM i, so not every shorthand command is listed on this page but a whole bunch of them are and it's really convenient to be able to refer back to this whenever you need to.
Creating a Package.json
When you're working with NPM there's really two kinds of projects you're going to be working on. The first one is going to be your typical project where you're building something for users. It's a website, a web application, something of that nature where there's going to be users that are using it of some kind. The other kind of project that you deal with with NPM is a third-party package, something you're going to build for other developers to consume. We'll talk about building packages for third-party consumption later on but for now let's talk about the first kind of project, a project that you're going to build probably for other users or yourself to use. With this kind of project there's a couple of reasons that you'll want to create a package.json file. The first is to track the dependencies of the packages that you're using, so whatever packages that you download and install through NPM, you'll want to keep track of those and the other reason is it's a quick and easy way to create some little scripts. This will help you avoid having to install grunt or gulp just to save you a little bit of typing every time you want to start your project up. We'll talk about scripts later on but for now let's talk about just creating the package.json file. The command to do that is NPM init. This command is going to walk you through a series of questions. Now, those questions are going to change as versions of NPM change so you may not see the exact same questions that you'll see here but even so the differences will be fairly minor. One nice thing about NPM init is that it will give you defaults for every answer so nothing is truly required. You can just hit enter at every point and create a default package.json file. Now, the nice thing about the fact that it gives you all these defaults is that these questions really don't matter. If you're not publishing this as a package in NPM, then this information is completely for your own benefit. If you publish your project on GitHub, other people may see this information but the accuracy of this information really isn't going to make a difference. So, for the name I'm just going to accept the default here by hitting enter. Version 1.0.0 is just fine. Description, I'll just leave blank. For the entry point I'll accept the default. Test command, default. Git repository, default. Keywords, default. Author, for this I'm going to fill in my own name just for vanity purposes but again, this really doesn't matter. License, I'll accept the default. At this point it actually shows me the package.json that it's going to create and one thing that you'll notice is it's a little smart. I've already installed Express and it's picked that up and put that into the dependency section for me, so if I create this package.json after I've been developing for a while, whatever packages I've already installed are going to show up there in the dependencies section. Then I just hit enter to accept this as being okay, and my package.json file has been created. Now, you can always create a package.json file by hand but I find that it's so quick to type in NPM init and then just hit enter a whole bunch of times, have it create my package.json file for me and if that's all you're going to do is just accept all the defaults, there's actually a faster way. If you type in NPM init and -y, then NPM will quickly create a package.json file for you with all the default answers accepted.
After you've used NPM init a few times you'll find that there are several setting that you'll keep the same every time. Using the NPM set command you can set some defaults for NPM init. For example, if you want to set the author name, you could use NPM set init-author-name and then put in your name as you'd like it to appear. To get a list of these defaults you can set, if you go over to the NPM documentation, under using NPM under the config section and search for inti-, you'll find a list of these settings. There's init-module which isn't too useful, author-name, author-email, author-url, license and version. We've already set the author name to default, let's also set the license and we'll set this to MIT and now if we use NPM init and we just accept the defaults it will include our author name and the default for the license is now MIT. If you want to check and see what one of your settings was set to, you can use NPM get and the name of the setting you want to check. If you'd like to remove a specific setting, you use NPM config delete and then the name of the setting. The reason we have config in there is because the NPM set and NPM get commands are actually short for NPM config set and NPM config get. All these settings go into your NPM RC file which is in the root of your user directory and we can see this file by looking at the root of our user directory. And that's where all those settings are contained.
Installing with NPM is very straightforward. You really just need to know the name of the NPM package and then you could install it using the NPM install command where the name of the package comes after the word install. In most cases, the name of the package inside of NPM is going to correspond 100% with whatever you call the name of the package. So, lodash is lodash, angular is just angular, express is just express, these all just use the same name inside of NPM as the names of the libraries themselves but there are plenty of examples of libraries that have a slightly different name inside of NPM. So, in this case, you'll need to know the name of the library inside the NPM registry in order to install it. For example, there might be an ion drive library that just calls itself by the name ion but inside of NPM the name might be ion-drive because somebody else has already taken the word ion for the name of their package. When installing a package such as lodash, if you want that dependency saved into your package.json file, you'll need to add the --save flag. This will write it into the dependencies section of your package.json file. There is a shorthand version of this which is just -S, so if I execute this, and then I look at the package.json file, you can see that lodash has been added to the dependencies section. There's a shorthand version of install where instead of writing out the entire word install, you can just write in NPM i, like that and that will also work when installing a package. I really prefer this way. It's only a few characters but still, it's a lot easier to type in NPM i than the name of the package. Now, if you're installing a package that you don't need in production, you just need it for development, such as karma which is a testing package, then instead of saving it into the dependencies list, you're going to want to save it into your dev dependencies list and you can do that with a --save-dev command and a shortcut version of that is just -D. Karma actually takes a while to install, so if you don't need it installed, don't execute that command. But once we've executed that command, we can see that it's now in our package.json file and it's there in our dev dependencies section. There is one other section in the package.json for your dependencies which is the optional dependencies section but nobody uses it so you can safely ignore it. If you do happen to run across it being used, it was probably either done by somebody who really knows what they're doing or has no idea what they're doing and it'll be up to you to figure out which one it was.
Listing Installed Packages
Now, if you need to see which packages you've installed in a project, you can always get a list of them just by doing a quick directory listing like this and just look at the directories in your node modules and you'll see that I've installed two packages, jshint and lodash but NPM has a command called list which will actually give you a list of all the packages that you've installed with their dependent packages and it gives it to you in a nice graphical tree format, so you can see here even though I've only installed two packages, lodash and jshint, there's actually a fairly complex hierarchy of dependencies that are involved, in this case it's jshint that depends on all these other libraries. Now, there are a few options that you can give list in order to modify what it prints out. For example, you can give it a maximum depth, so if I do NPM list with the --depth command and give it a depth of one, that indicates that I only want to see dependencies one level deep and we can see the two dependencies that I've installed, jshint and lodash, and just the immediate dependencies that they have. If I give it a zero instead, then I just see the packages that I've installed myself. I can also use this to see what libraries I've installed globally which I use the --global flag and give it a value of true and that will print out all the packages that I've installed globally. I can also with that add the depth flag, and combine the two commands. There's also quite a few formatting options that I can give this command. For example, I can give it the --long command with a value of true which prints out a whole bunch more information about each of the packages. This can be really nice in order to see the description of the packages, the URL they're installed from, where their official website's at. I can tell NPM list that I want the output in a JSON format and it'll print the output in JSON, so that I can digest it with some kind of a program or I can use a passable format that isn't JSON and I can also limit it to just my dev dependencies or I can limit it to just my non dev dependencies. There are a couple of shortcuts for NPM list which are ls, or la, or ll. It's probably most common for people to use list or ls.
Installing Global Packages
There are times when you'll need to install NPM packages globally. The reason for this is not to be able to avoid having to install them in every project that you need that package but instead, this allows the package to create a command that can be used from the command line. For example, if you want to run gulp, you're going to need to install it globally otherwise the gulp command doesn't work from your command line. The same thing goes for grunt and karma. So, in order to install a package globally, use the same command, NPM install, the name of the package and then you'll use the -g flag. This will install the package globally. When a package is installed globally it doesn't get installed into the node module sub-directory of your current directory, instead it goes into a special directory on your computer. So, if you want to know what global libraries you've got installed, instead of locating that directory and looking at the contents of it, it's much easier to use the list command, adding the -g flag and then of course you'll want to use a depth of zero so that you just see the libraries that you've installed.
Removing a Package
Now that we can install packages, the next thing we need to be able to do is uninstall them when we don't need them anymore. That of course is a simple command using NPM uninstall and then the name of the library. In this case I've installed underscore, so I'll uninstall underscore and now it's been removed from my project but if we look at our package.json file, you can see right here that underscore is still in the dependencies. So, if we actually want to uninstall it and remove it from our dependency's section we'll need to uninstall it and add the --save flag. If we do this then underscore has now been removed from our dependencies. It's important to note that you must use --save. You cannot use the shortcut of -S. You can use NPM rm underscore. You can also use NPM un, which is short for uninstall, underscore and finally, you can use NPM r. Now, last thing. If you need to uninstall a global package, all you have to do is add the -g flag and then NPM will uninstall that package from your global repository.
Installing Specific Versions
Most of the time when we install a package we want the very latest version and that's what happens when we just give the name of the package. In this case, if I install underscore, I'm going to get version 1.8.3 but there are times when you want to install a specific version of a package. This is especially important in critical applications or updating a package to a new version might break your product and the consequences could be catastrophic. In those cases you want to make sure that you're only installing specific versions of libraries. This is particularly important in mission critical application but it can be important in other kinds of applications as well. When dealing with specific versions of packages, it's important to understand semantic versioning. Semantic versioning is a system of versioning whereby each of the three numbers means something to everybody and not just to the developers who decide what the three numbers mean. So, in the case of underscore which is currently at 1.8.3 each of these numbers means something very specific. One is the major version, eight is the minor version and three is the revision or patch number. We'll start with the patch number first. The patch number is only incremented when you make something like a bug fix or a performance improvement to a product, something that doesn't change functionality. So for example, if there was a bug in underscore that they fixed or a new performance improvement, they might revision it to 1.8.4. Meanwhile the minor version means that there are new features involved. So, if a new feature was added to underscore, then we would update the version to 1.9.0. In this case no existing functionality is broken but new functionality is added. In the case that you actually break functionality and do something that's no longer backwards compatible, that is the time when you update the major version. So, if underscore where you're going to do something as simple as change the signature of one of its functions and reverse the parameters, that would break existing code in which case our 1.9.0 would now become 2.0.0. Understanding this we can now understand how versioning works with NPM. In NPM if we want to install a specific version of a package, we can just use the install command with the name of the library, then an @ sign and the number of the specific version we want to install. So, in our case we might want to install 1.8.2 but we can get a lot more complex than this. For example, we might want to install the latest version of 1.8 in which case we can change the two to an X, or we can just delete the patch number itself. In this case, underscore will install the latest version of 1.8. If we change this to 1.7 we will install the latest version of 1.7. If we change this to 1.x then we'll install the latest version of underscore one which at this point would be 1.8.3. We can also just remove the .x and get the same functionality but we can be even more complex than this, for example, by introducing quotation marks we can use things like a greater than sign and then give a version number to say that we want anything past version 1.1.0, this would not include 1.1.0 itself unless we added an equal sign and we can also say that at the same time we want anything before 1.4.0. This will in general install the latest version of 1.3. We can even get more complex than this by adding in an or operator and another range but in most cases we really don't need all this functionality. There are three main cases that we want to handle. The first case is to simply install the latest version of a library which we do with syntax like this. The second case is to install a very specific version which we do like this by adding the version number after the @ sign. Finally, we might want to install the latest in a specific major version, for example, express is currently on version four and if we wanted to install the latest version of Express Three we could say anything before four or 3.x or just three and that would give us the latest version of Express Three and if we know that Express Three works, we can trust the authors of the library that they won't break any functionality in any version of Express Three. Now if I just want to install the latest version of underscore and I add the --save option, then my package.json file would be modified and we can see that underscore has been added as a dependency but this little caret right here means that if underscore publishes a new version and goes to version 1.8.4 or 1.9.0 that NPM will install that latest version and not 1.8.3. In most cases that's just fine but if I want to install a specific version of underscore and not let NPM upgrade me to the latest version, then when I install underscore, and give it a specific version number, of course I'll need the --save flag but I'll also need to add the --save-exact flag. This flag will work with both --save and --save dev. If I install like this, then my package.json lists 1.8.2 without the caret. That means that NPM will only ever install 1.8.2 for me and not automatically upgrade me to a later version of underscore. This is the kind of thing you want to do on mission critical applications with large teams where you only want to upgrade your dependencies to newer versions under very specific circumstances after evaluating and testing that the new dependencies don't break any existing functionality.
Installing Existing Dependencies
One of the great features of NPM is the fact that once we get our package.json file set up, when a new user wants to install the dependencies for this project, all they have to do is type in NPM install. So for example, our current package.json file contains one dependency underscore, so if I type in NPM i, then NPM goes ahead and installs underscore for me. Now let's look at this version number noted next to underscore. We've got the file open in an editor and we haven't specified that we're going to install 1.8.3. So, what happens if I change this to 1.8.1? Let's go back in and we'll remove underscore but we won't add the save flag so that it won't remove it from our package.json file. We can see it's still in there. So, let's now NPM install, and you can see we're still getting 1.8.3. That's because of this caret in front of the version number. In fact, even if we change this to 1.7.1, uninstall again and then install, we still get 1.8.3 which is currently the latest version of underscore. So, if we want to change that functionality and say install the latest version of 1.5 but at least version 1.5.1 and then we remove and install again, and if we change this caret to a tilde and then remove and install again notice that we're now getting the latest version of 1.5 which is 1.5.2. The tilde means that we only want the latest version of the minor release, whereas the caret means that we only want the latest version of the major release. Now, if we don't care and we just want the latest version of the library, we can change the entire thing to either an asterisk or an X and then we will simply get the latest version of the library whenever we install no matter if the patch, minor or major version has changed. Of course, if we just want to install a specific version, then we don't use any character, it's a prefix and we just put in the version number itself exactly like this and now when we install we will get that exact version and that exact version only.
One of the great features of NPM is the ability to easily update your dependencies to their latest version. Here in this sample I've got a package.json file that specifies that I've got underscore as a dependency at version 1.8.2 and jshint at version 2.7.0. Both of these have a caret which means we can update to the latest minor version but we're not going to update to a new major version. I've actually got installed versions 2.7.0 and 1.8.2. Now, both of these libraries have a newer version than this so in this scenario we installed these earlier on and now they've been updated to a newer version. With NPM whenever I want to update to the latest version, all I have to do is type in NPM update. At that point NPM goes out and grabs the latest compatible version of all your dependencies and updates them. If I now check and see what I've got installed, we can see that I've got jshint 2.8.0 and underscore 1.8.3 which is currently the latest versions of those two libraries. By default when you install a package like underscore and use the --save flag, it will install with the caret in the package.json to indicate that upgrading to the latest minor version is just fine, just don't upgrade to a major version. That way if the library author follows semantic versioning we shouldn't ever have any problems whenever we run NPM update. So, the default path shouldn't cause us too many problems. Of course occasionally authors make mistakes and do updates that actually break our projects but for the most part, this is really safe. Now, you may want to just update your dev dependencies, in which case you could do NPM update --dev or you may just want to update your production dependencies which will be --prod but in general, if you're going to do an update, you're probably going to want to update all of your dependencies. The other common scenario is just wanting to update a single dependency to its latest version. So, let's reinstall underscore version 1.8.2 and then we'll NPM update underscore and that will update just underscore. That way we can update one dependency at a time, test our project to make sure that it's still working, and then upgrade another dependency. The final thing you may want to do is update your global dependencies. You do that of course by just running NPM update and adding the -g flag. Now, since this may update a lot of libraries, you may want to be careful about when and how often you do this. You may want to do this on a library-by-library basis, maybe doing just one library at a time.
Installing from a Git Repo
When you find a module on GitHub that you want to use, almost all modules are going to tell you how to install them with npm. For example, here's the page for Express, and you can see right here that it gives us the command, npm install express. But you may find a repo online that you don't know what the name is for it in npm, or it might be a fork of an existing project that's been modified for some reason, maybe custom to you, and therefore you have a GitHub URL that you know that you want to install from, but you don't necessarily know what the npm install name is. In this case, you can install directly from GitHub, using just the URL. So if I wanted to install Express from a URL, I can just give it the full URL, and that's going to install Express for me. This is exactly the same as if I were to type npm install express. And one thing to note about this, is it's not limited to just GitHub, if for some strange reason you have a package that's available on some other URL, you can just type in that URL as well, and npm will install it from that location.
Installing from a Gist
Sometimes, we need to install a Gist as a module. This can happen when instead of forking an existing package, you create a gist out of it and make some changes. And then you want to test those changes as a dependency of an existing project. Here I've created a very simple Gist with just two files: an index.js that does nothing more than log out the message, "Hello Mars!" And then a package.json which has the basic information about this package. Notice that every Gist has a hash appear in the URL. If we copy this hash, then go to our project and type in, npm install gist, a colon, and then paste in the hash, this will actually install that Gist as an npm package. Now it's very important that the Gist itself have the package.json. This will not work without it. Once it's installed, if I list out my packages, you can see we've got this Hello Mars package listed. Notice that it's marked as extraneous. We can actually save it into our package.json by installing it with the --save option. And now, when we list it out, it doesn't mark it as extraneous. Now you may see this listed as invalid instead of extraneous. You can ignore that, it has to do with it not being in the npm registry, which for a package like this, we don't care about. And if we look in our package.json, it's listed there, but instead of a version number, we see that it's a Gist with a hash.
Installing from a Folder
Sometimes you may need to install packages that are private and not published in the npm registry. This is more common in larger organizations, which may have a very large software base of closed-source software that they don't want to publish to npm. But they still want to create components as packages, and allow other developers to be able to use those packages, and install them just like regular packages from the npm registry. A great way to do this is to create these packages, and then store them on a shared folder somewhere on the company's network. Or put them in Dropbox and then use Dropbox to sync them up onto developers' computers, or even publish them to a private website. In the case of publishing them either to shared drives or using Dropbox's folder sync option, the package is going to be in a folder somewhere on your computer, and you want to install from that location. NPM is just fine handling this. It can install from a folder somewhere else on the same computer, or even from a network drive. All you need to do is give npm install the path to the folder. In our case, we're going to install our Hello Mars package from a sibling to our current directory. This has successfully installed that package and if we list our packages out, we'll see Hello Mars is listed, of course as extraneous so if we install it again but this time with the --save option, and it's now listed in the package.json file, and is no longer listed as extraneous. And like Gist, this may show as being invalid, in which case you can just ignore that.
The NPM Registry
The npm registry is basically just a big huge list of every package that has been published through npm. The main piece of the registry is the package.json for each package. When you go to npmjs.com and search in this find packages box, you're actually searching through the registry. Once you select a package, you're seeing the registry information about that package. There's a couple of other things that you can do with the registry that can be useful. For example, if you go to registry.npmjs.org, and type in the name of a package, you'll actually see a json version of the npm information for that package. Another nice thing that you can do is if you type in npm.im/ then the name of a package, it will take you directly to the page for that package. This can be really useful when you know the exact name of the package you want to see, but you don't want to take the extra time to go to npmjs.com and use the search box.
Searching for Packages
NPM has a search feature, that's just npm search, and then any keywords that you want to search for. Say for example you want to search for packages that are related to underscore, this will search for any package with the word underscore either in the package name or in the package description. Unfortunately, the npm search facility can be quite slow and the results aren't necessarily the most useful results that you can get, due to the fact that you're looking through a lot of information on the command line. The search function searches the npm registry. Thankfully there's another way to search the npm registry that's a actually quite a bit better. If you just go to npmjs.com, there's a search box right here that you can type in a search phrase, and not only will it give you suggested results underneath it, but if you hit enter, then search and list all results. And if you search for something a lot more specific, like underscore mixins, and get a much more limited set of results. And they come back instantly and now you can go and click on one of these results and see the detail page for that particular package.
Sometimes, in really large projects, you install packages that you don't mean to install, or you stop using a package and want to remove it, or maybe you try out a package and decide that you don't need it. You can always use the npm remove command, but if the package isn't specified in your package.json file, either because it was never in there or you deleted it from your package.json file yourself, then you can use the prune command instead. Let's go ahead and run an npm list, with a depth of zero, on this project, and you can see that I've got grunt, jshint, and underscore installed, but you'll notice that there's an error that npm is reporting that grunt is extraneous, and next to grunt is this little green extraneous. This means that grunt is not specified in our package.json file. Indeed if we look at it, we can see that we've got underscore and jshint specified, but no grunt. So if I were to run npm prune, npm will go through, compare the packages that I've got installed with my package.json file and remove anything that shouldn't be there. And now if we list out our packages again, we're clean. You can with npm prune add on the name of a library, like grunt, and then it will prune just that one, but that's essentially the same as doing a remove. The other scenario that prune can be useful in is when preparing to deploy to production. In that case, if you add the --production flag, this is going to remove all of your dev dependencies, which will leave your package ready to go to production. You can see that it's removed jshint, and now the only package that I've got installed is underscore, which is the only one that's specified in my production dependencies list.
The NPM Repo Command
Sometimes when working with a package, we want to go and see the official website, or go look at the source code for the package. That's where the npm repo command can come in handy. Repo works by typing in npm repo and then the name of a package, in this case, let's do underscore, and that will ask npm to take you to the official repository for that package. So you can see it's opened up a browser and navigated us directly to the underscore repository. From there, I can look at the source code, I can go down and get links to the official website and other information, so this can be really handy. Of course you can usually find this same thing by using Google, but sometimes, especially for more obscure packages, this is a lot easier than trying to find it with Google.
You may at some point discover that you need to upgrade npm itself. This is actually fairly easy because you can install a new version of npm just exactly as you can with any other package by using the npm install command. There's just a few things you need to keep in mind. The name of the package is npm, of course, and to be clear we'll use @latest to get the latest stable version of npm. It's a global package so we add the -g, but most important: you must run this with administrator privileges. You'll notice that I'm in a plain Windows command prompt, and at the top, it indicates that I'm an administrator. Especially on a Windows box, if you do this without administrator privileges, it possibly can mess up your entire installation and you'll find the only remedy is to reinstall node itself. So as long as you do that, then this is the command that you can use to upgrade npm. And there we've installed the latest version of npm.
Using Simple Scripts
The ability to write your on scripts using npm is a very useful feature. One of the nice things about it is that npm supports simple scripts and there are some customary scripts you can write that are easily supported by npm. When you first start off with the default package.json file created by npm init, this is roughly what the script section will look like. It'll have a default test script that when run will simply echo out that no tests are specified, and then exit. Let's first look at how to run scripts and the two main default scripts that npm supports. We'll start with our test script. In order to run the test script, you simply type in npm test. That executes the script which we saw, which simply prints out to the console: npm ERR: Test failed. Now if we want this script to actually do something, we can go in and change the script itself. So in our case, let's run our test file by typing node test.js, which will execute the test.js file in node. And now if we go out and run the same script, we can see that it's run our test script, which prints out that five of five tests have been run. Zero failures. Now of course in a more typical project, you'll probably be running something like karma, in which case you could put the karma command here inside the test script. The next script we want to create is the start script. This is the other default script that you will commonly see in most projects. By convention, the start script is the script that you'll run in order to launch the project. In our case, we want to run our index.js file with node, so we'll just use the script node index.js. And now if we run npm start, it will execute our index.js file, which prints out two messages: "Let's go to Mars!" and, "Hello Mars!" Again in a more typical project, you might do something like launch http-server, telling it what port and subdirectory to start from, or maybe even live-server, or something to that effect. These are two of the default supported scripts and the two most common ones that you'll want to use. There's actually a large set of other script names that are supported besides just test and start, and you can see that list here in the npm documentation. There's quite a few here, but by far most of these are not scripts that you're going to use yourself. In most cases, you're only going to be using test and start, and then you'll be using your own custom script names. For example, if you wanted a special script that would uglify your code, you could put in the key uglify, and then a script for that. In this case, we use gulp compress, which uses gulp's uglify task. I've already specified the necessary information in my gulp file, which we can see here. This is just a very simple compress task. And now if I want to run this task, I'll go back to the command line but instead of typing in npm uglify, which is how we might think we call this script, instead we have to use npm run, and then the name of the script, which runs the compress task in gulp, which then creates this dist folder, that has compressed our index.js file and you can see that here. Now you might look at this and say, "Well, if I'm going to type in "npm run uglify from the command line, I can "instead just type in gulp compress, "which is what ultimately gets run. "So why bother with the longer command?" Well, that's true to a point, but remember this script section inside of your package.json file is a central place for all the scripts that you need. And they're all right together, one line after the next. That way, somebody doesn't have to go into your gulp file, look through it, and find the tasks that they want to use. You can give them prompts by creating this script section inside of your package.json file. And of course if you're not even using gulp at all, then you can still do a lot of simple tasks using simple commands like the ones that we've seen here.
Publishing Your Own Package
Setting up Your NPM User for Publishing
In order to get ready to publish with npm, you've got to prepare your user for publishing. For most people that means they'll actually have to create a user account with npm first. In order to do that you go to nmpjs.com and click sign up. From here, simply follow the prompts in order to create your user account and be sure to remember your user name and password. At that point, you can go out to your command line, you'll need to add the user using the npm adduser command. Executing this will prompt you to type in your username, your password and enter your email address. Once you've done all that it will add an npm authentication token to your npm RC file. Your user is now setup and you can begin publishing packages.
Preparing Your Project for Publishing
In order to get your project ready for publishing, you've got to do two main steps. One is set up your project in git and two is create the package.json file. We'll start off by setting up our project for git. Right now, my project is blank. All it's got is my index.js file, so I'm going to create a git repository for this using git init. Now, I've got my repository created. You may have already done this step yourself. In my case I've already created my GitHub repository, but if you haven't created your repository, you simply go to your GitHub page and create a new repository for the project that you're going to be creating. Fill in the name and description and click the create repository button. If you're not familiar with GitHub, you can check out one of Pluralsight's courses on using GitHub. Once the repository is created, you'll need to associate your local files with that repository and we do that using git remote add origin and the URL to the GitHub repo. In my case, this is my URL. Of course, yours will be different for whatever package you're creating. This is the critical piece we need setup before we create our package.json file, which I'm going to do next using npm init. Now this time through npm init, I've really got to pay attention to every question asked because they really matter when you're creating a package that you're going to be publishing. The name matters because that's going to be its name in npm and that's going to be the name that people use when they want to install using npm install. In my case hello-mars is just great. The version can really matter. If you are in pre-release, you may want to start with a 0.1.0 or something like that, although 1.0.0 is really just fine, so I'm going to go with that. I'll give it a description and for the entry point, if this is a module that's going to be consumed by other people, which it typically is when you're publishing with npm, then you really need to make sure that you get the right entry point. Of course, mine is index.js. I'll leave that as the default. For a test command, I don't have tests, but your project may have tests, in which case you want to put in what your test command is. The git repository is automatically filled in for me. I can override this if this isn't correct and a list of keywords, I'm just going to put in mars. For the author, fill in my name and finally for license, I'll accept the default. Now, it prints out to me what my package.json file is going to look like. I can double check it all and make sure it all looks good and then hit okay. Now, I've got my package.json file created and my project is ready for publishing. Of course, if you walk through these same steps that I have, you're going to probably want to check in all your files and push them up anyway with a git add ., git commit m and your comment and then a git push. If you haven't set your upstream like I haven't, you'll want to git push origin master and our project is set up and ready for publishing.
Publishing Your Package
Publishing our project is a really simple matter of just using the npm publish command. Once we have our project all set up, npm publish is all we have to do in order to publish it to npm. You can see that after I've executed that command, it's gone ahead and published my project. You'll also see the version number that you've published. Mine is set at 1.0.2, but yours will be set at whatever you've got in your package.json file. Now that we've got that published we can do things like npm info that's our package name. You can also use npm repo and that will take you to the repository for your project and if you want to go to its npm site directly, you can do npm.im/name of your project and it will take you to the package's home page. Now publishing to the package is great, but that's really only half the story because your package was also on git and you'll want to release on git that's the same as the version you just publish to npm. We'll go back to the command line to do that and we're going to issue the git command, git tag and then the name of our version. In my case, it's 1.0.2. In your case, it'll be whatever version you just published. Now only do this after you've already committed and pushed your changes to your files that you've published through npm. Issuing that will tag the release and now you can push that tag up to GitHub using git push - tags. Now if we go back to GitHub, we can see that tag by clicking under the branches button and there's both a branches and a tags tab. We'll click the tags tab and we'll see our 1.0.2 tag. If I click on that we can see this version 1.0.2 tag. we'll also note that this is marked as a release in GitHub, so people who come to your repository for your package wanting to look at the source, can come in here and find the associated release with the version that they're working with. This is something you really must do in order to play nice with the ecosystem of npm. You don't want users coming over to your GitHub repository and not knowing what version of files match the version they're using on npm. That will create problems not only for them, but also for you as they submit issues on GitHub. That's the basic process for publishing, just use the npm publish command, tag it and push the tag up to GitHub.
Publishing an Update
Publishing an update to a package is a really straightforward process. It basically involves three steps, first, making the changes to your code, second, updating your version and then three, walking through the same publish process that we did when we were publishing our package initially. Let's make a small change to our code. Let's assume that we're going to add an extra exclamation mark. We'll save that change and we're going to need to update the version of our package. We can go directly to our package.json file and manually update the version by just changing it here. Now, we need to look at the nature of the changes that we've made in order to understand which part of the version number we need to change. In our case, we haven't changed any functionality. There's no new functionality, we haven't broken anything, so this is more like a bug fix, in which case we're just going to change the revision or patch number, but if we had added new functionality, say we'd put in a language parameter here and then based on the language, we're going to print out a different message to the console, then we might want to update the minor version so long as we include a default, so that if they don't pass in a language, then it still prints out a message. Now if we made language required, we'd actually be breaking functionality, in which case we're going to want to update the major version. Now, we can do all this manually by just adjusting the package.json file or we can let npm adjust the version number for us. Let's go back to our index and we'll just make the one change that we're going to have two exclamation marks in our message. Then, we'll go out to the command line and we're going to commit our changes using git add ., git commit. Now that we've got our changes committed, we can use the npm command version, which takes one of three options, either patch, meaning that we're going to change the patch number or minor, meaning that we're going to change the minor version number or major, meaning that we're going to change the major version number. In our case, we'll just change the patch number and now you can see it's printed out version 1.0.3 and if we go back to our code and look at our package.json file, it's been updated automatically to 1.0.3. Now, if you've been following along closely, you may have noticed something, we checked in our changes to the index.js file, but we didn't check in any changes to the package.json file, yet we've changed it. If we go back out to the command line and we do a git status, you may expect to see the package.json has been changed, but we're going to see that our working area is clean, there's nothing to commit, although you may notice that it says that we're ahead of origin by two commits. If we do a git log, you can see that our last two commits are fixed message commit and then after that is a commit with just the message of 1.0.3. What's happened is npm itself has made a commit for us. The other thing that npm did for us is it actually tagged that version, so if we just do git tag, we can see that we've got our 1.0.2 and the v1.0.3 that npm created for us. There is a small difference in there, the npm uses a prefix of V. That's fine for our purposes. That really doesn't matter. Let's go ahead and push our changes and add the -- tags option and that will push up our new tag for us. We've also got to issue just git push in order to push up the file changes. Note that those have to be done separately, unless you dig into git and set a configuration parameter, but that's beyond the scope of this course. Now with everything pushed up to GitHub, we can simply issue npm publish and we just released version 1.0.3 of our Hello Mars package to npm.
Releasing a Beta Version
Finally, let's talk about releasing alpha and beta versions. Here, I've made some changes to the code to actually support languages. The changes should be backwards compatible because even if you don't pass in a language, you're still going to get the default message we were getting before, but if you happen to pass an es for Spanish, you're going to get Hello Mars in Spanish. I like to publish this but I'm not really sure how this is going to be received. I'd like to let users try this out and give me feedback, so I want to release a beta version. Well, beta versions are well supported by npm, you just have to follow the semantic versioning conventions. In this case, we're going to update this to 1.1.0, but we're also going to add a -beta.0. This version lets people know that the product is currently in beta and this is the initial version of beta as we adjust it and try new versions that are still in beta. We can increment 0 to 1 to 2. Now, npm does not support adding beta to the version like this, so we have to do this manually. Let's save this change and we'll go out to the command line. I'm going to add those changes and then commit them. With changes committed, I also want to tag this in git. I'm going to give it the same version for the tag as I gave it inside of my package.json and now I can push my changes and push up the tag. Now, just like publishing a regular version, I'm going to use npm publish, but I'm going to add on the - tag with a label of beta. This is going to publish this version, but tag it as a beta version. Let's go ahead and do that and then we'll talk about what that means. Tags are really interesting feature that npm supports and we can see their use when we install a version. If we were to install Hello Mars using npm i hello - mars, we can use an at and then a tag name. In this case, it's going to be beta and that would install the beta version of Hello Mars. If we use latest, there could be other tags that we could put in place of this or we can use of course just a version number, but let's see where those tags come from. If we use npm info, we can see the information about that package. If we scroll up a little bit and look at this dist tags key, you can see two entries. There's latest, which is set at 1.0.3 and beta set at 1.1.0-beta.0. By default, whenever we publish a version, npm will update our latest tag with that version, but if we specifically tag it when we publish, then it will create that tag or update that tag to whatever version we're publishing. By default, every package already has a latest tag, but we can add our own tags like we did with the beta tag. Now, of course, it's conventional to use beta, but we could use any tag that we wanted. We could call this trial or test. Of course, stay away from non-standard names like that. Alpha and beta are the kinds of tags that you want to use. Things other than that are really not conventional and you should stay away from them. Now if we were to go out to our trip-to-mars and we were to npm install hello-mars and put the at latest tag, then you can see that we've installed Hello Mars version 1.0.3. This is exactly the same as just npm installing Hello Mars without the latest tag, but if we want to specifically install the latest beta version, we add the at beta tag and you could see that we've installed Hello Mars 1.1.0 beta version. This is showing up as invalid because it doesn't match our dependency specification inside of our package.json file, which we can fix by going into our trip-to-mars and adding in this version number 1.1.0-beta.0. Now if we list this out, it shows up without the invalid flag. This is how you can publish beta versions of your package to npm.
Joe has been a web developer for the last 13 of his 16+ years as a professional developer. He has specialized in front end and middle tier development . Although his greatest love is writing...
Released11 Dec 2015