This course has been updated! We now recommend you take the Introduction to Node.js, v3 course.

Check out a free preview of the full Introduction to Node.js, v2 course:
The "Setup a CLI Script with Node.js" Lesson is part of the full, Introduction to Node.js, v2 course featured in this preview video. Here's what you'd learn in this lesson:

Scott creates a command line interface (CLI) using Node.js. By including the installation directory at the top of the module and specifying the command on the bin object in the package.json file, the Node.js package can be installed globally using npm and executed from the command line like other CLI tools.

Get Unlimited Access Now

Transcript from the "Setup a CLI Script with Node.js" Lesson

[00:00:00]
>> So you should feel pretty comfortable searching for and installing packages, to try out and use in your development and I encourage you to do so. I think especially for someone new to learn to code, there's always this misconception that, you need to know everything. Everything needs to be created from scratch, you have to just know how everything works.

[00:00:21] Well, I don't think really anything works like that, in the world, especially in engineering. We all piggyback off of previous knowledge, and people that have come before us or even that are just better than us at something specific. So you don't have to recreate the wheel every time, and you should be leveraging the community by pulling it down and trying it but also giving back and creating.

[00:00:41] When you do find something that's useful for yourself, you might not understand or you might not know who else it could be useful for, and I really encourage you to try both of those things, so using PM it's amazing. Don't try to do everything from scratch because, someone probably already solved it, just install it.

[00:00:59] The next thing I want to talk about was CLIs or command line interfaces, so we've been using CLIs pretty much this whole time. NPM is a CLI, node is a CLI, pretty much any program whose interfaces on a command prompt like a terminal or wherever you might be writing this code.

[00:01:19] That's a command line interface, it's just a fancy name for an app that runs in the terminal. And you interact with it through like a command and some texts and prompts and different things like that. I would say that there's no visual representation or visual interaction with the CLI, but these days people create like some crazy stuff with CLIs, I've literally seen someone render a 3D floating doughnut in a terminal with a CLIs.

[00:01:43] So I was I feel like I can't even say that anymore but for the most part, there is no UI here for a CLI it is interacting with the box. So, we are gonna create a CLI so if you've never created a CLI before, you're gonna have fun doing this, I promise you.

[00:02:00] I tried to make this one pretty fun and relatable and usable. So I'm gonna walk you through how to do that so you can get your own little custom command inside of the terminal. And you can see how node makes that easy compared to a lot of well I wouldn't say that it's easier than everything else, pretty much every language is pretty easy to create a CLI.

[00:02:21] I know, Dino makes it super easy to create a CLI that's one of the biggest features I like about that but NodeJS is no slouch either, and so we're gonna figure out how to do that just now. So the only difference between a CLI and a typical NodeJS app is you just need to add a little bit of more information to be able to have it consumed in the correct way when someone installs it.

[00:02:44] So what we're going to do is we're gonna create a CLI that interacts with Reddit. I want the CLI to be able to go to Reddit, and open up a random Reddit post that's on the front page. It will open up in the browser for us all we had to do was run the CLI, and we shouldn't have to worry about what's going to happen.

[00:03:03] Like if you'd like to Reddit you'll probably like this if not, welcome to Reddit, so let's do that. So the first thing we're gonna do is let's create a folder in our little app here, so we'll make a new folder, not here but here, and I'm just gonna call it reddit-cli.

[00:03:23] And then because it is a package, we need this to be a package for many reasons, one that we're gonna be installing other packages. And two, we're probably going to eventually have other people consume this CLI as a package for their own so we needed to package for both ways.

[00:03:39] So we're going to change directories into that, and we're going to run npm init. And I'm just gonna hit Enter on everything, get the defaults, good to go. You can also skip that if you do npm init, and I think you do --yes, or --y or something like that, it'll do the same thing, it'll just skip all of it.

[00:04:03] So we got that we got our package JSON here, I'm gonna add a git ignore, cuz it's just a habit at this point node modules. And there's a bunch of other stuff you should be adding here, but we'll just do node module cuz that's an important one. I don't want that being tracked, slowing down my computer, and my terminal and all that stuff, so we'll do that and put that in there.

[00:04:23] And then what we're going to do is we need to figure out what dependencies we need to install. But before we do that, we just want to get the CLI set up before we even do the logic of interacting with Reddit, let's just see if we can get a CLI to work.

[00:04:40] So the first thing we have to do is, we need to just figure out we need to create a file where the entry point to our CLI is, what's the file, what's the entry module, what's going to be executed when someone runs this command line. So we gotta tell node NPM where that is, and then we have to make sure that it's executed in the correct interpreter.

[00:05:02] So in this case the interpreter will be Node we don't want this file being executed against Python or Ruby, or Java, we want it to be executed against Node. And because we don't know how you're gonna install this on your machine, we need to make sure that we're explicit about that instruction that hey, this needs to be installed to Node.

[00:05:20] So we're gonna use something called a hash bang that's gonna sit at the top of the file, it looks just like this. And this is going to tell your computer your OS hey this file, this command needs to be executed against the Node interpreter, and here is the path that it's usually installed into.

[00:05:37] So it's the location to the Node on someone's computer and it's gonna try to execute it against that. So the reason this wouldn't work is that this person didn't have Node in this section. If you use NVM, NVM actually puts it here for you, it's creates like a symlink so you're good, if you use the native installer, that's exactly where it goes so you're definitely good.

[00:05:55] So we're gonna do just that so, we're gonna make a new file here, I'm just gonna call it reddit-mjs so. And I'm going to add that hash bang like this by copy it, Don't forget to hashtag. Why didn't it copy that hashtag?. Or I guess I didn't copy it, there we go, and if you did it correctly you'll see it kind of looks like a comment because it's not really code, right?

[00:06:25] Just to show you that this is actually a comment if I were to execute this node reddit.njs, nothing happens. I don't see anything breaking or anything like that whereas, I just get rid of that. And you can see that is obviously gonna break because that's not valid. JavaScript thinks it's like a regex or something so, this gets treated like a comment node is very much aware of this is not like a hack, this is a real thing.

[00:06:50] So now that we have that, I'm just gonna do a console log, so I'm just gonna get the hello word going. Hello from Reddit, CLI, so we got that. So we're almost there, right now we could execute this in the node runtime and it works. But the whole point is that I wanna be able to come in here and say, Reddit and hit Enter.

[00:07:11] I don't wanna type in Node Reddit that's not a CLI that's gross, I want a nice CLI. So, we could do that we can go to our package.json, and then we can add a new field here called bin. And in fact, we can just look back here, you'll notice that the node interpreter is installed in some folder called bin.

[00:07:34] You can think of bin is the folder where all your CLIs get installed all your global commands they get installed in a bin folder. So we need to register a new command in the bin folder, we can instruct NPM to do that for us when someone installs our Reddit CLI, by putting something in the packag.json and that's gonna be on the bin field.

[00:07:57] So if we go to bin, we put an object here now like that but like this, and then it's just going to be key, which is the name of the CLI that you want. In this case, we want to be able to run a command called reddit, so we'll put reddit here, and then the path to the entry file to it so in this case, the entry file would be reddit.mjs so like that, we'll put that there.

[00:08:23] So in this case, because this is a CLI and this application is not meant to be consumed by an import. I wouldn't expect you to npm install my CLI, and then import it into your app, unless I explicitly said hey you can also use this CLI programmatically, by importing it.

[00:08:43] Most of the time, that's just extra work for developers, so they don't always do that, so it's usually just only consumed by a CLI. So in that case, this main field probably just gets ignored, right? This main field is only for when someone's importing, or requiring your application, whereas in this case, it's a CLI and we don't plan on having programmatic access.

[00:09:01] So you could think of this as like the main field when it comes to the CLI and not this so you can kind of ignore that, so I just wanted to clear that up. So now we have the bin here and then the last thing we need to do is, we need to install our own CLI on our computer.

[00:09:17] And no we don't have to like publish it to the NPM registry and then install it back down, that would just be ridiculous. Although sometimes I've had to do that for conflicts and version reasonings, and it's really, really bad. But we can actually just do npm install -g, as long as we're inside of the directory of this package, by putting no arguments at the -g, it's going to install the package that you're in globally, is going to stall that globally.

[00:09:43] And during this installation process is when npm is going to see that bin field, and register that command for us that points to that file. So let's give it a try so, looks like I already did this earlier so I'm gonna try to, uninstalled this or let me see.

[00:10:03] Let me just delete this actually, rm -rf that and I will try to do it again okay cool so looks like I installed it, everything looks good. Cuz I'm using nvm that's gonna create like a symlink and all that stuff is good to go so I was able to do it.

[00:10:24] If you're having trouble with global install locally, what you can do cuz I've had this problem before, is if you delete all of your or not delete but you uninstall NPM. Uninstall, -g, if you run that and just uninstall all your globals then try to reinstall this one usually clears up a lot of errors.

[00:10:47] But I have run into some errors before as you just saw, with installing globally with NPM. And then with Yarn, it doesn't happen sometime, so I don't know if you're having problems with NPM, if you have Yarn try that if not just uninstall all your global stuff with NPM uninstall.

[00:11:03] If I can spell that right on install -g and uninstall all this stuff and then try again. So once we got that installed, we should be able to come in here and say which, if I can spell reddit and you can see, I do have reddit here confirmed, everything's good to go.

[00:11:20] So I should just be able to type in reddit and you can see right there hello from the reddit cli, and that's it, that's how you create a CLI. It's not a good CLI and I mean, it's not something I would ever use it doesn't even have a help command, I mean, it just does the same thing over and over again.

[00:11:35] So I wouldn't say you could go raise funding just yet but, yeah you got the gist of it. It's just two small lines of code, and you add a bin and then you add a hash bang to the top of your entry file, and then you're good to go.

[00:11:50] So he's got to be a little clever about how you named the CLI, you never know who else also has that CLI installed on their machine and, how that resolves and different things like that. So you kinda got to be clever with the name, there's really no right way of getting it right.