Create your own npx starter command like create-react-app

You may have used create-react-app to create new React Projects. In this video, you will learn to create your own npx starter command for your projects.

It is full of demo and lots of great information!

Full Transcript

Hello, it's Harit from bonsaiilabs. Today, I will demonstrate how you can create your own starter commands to be used with npx.

You may have used create-react-app starter command to spin up new React projects. This command installs the necessary dependencies in a new project and presents you with a welcome message. This is a great way to start your project from a template. I will show you how you can create your starter commands like create-react-app.

The key npm command which is responsible for such magic is called npm-init. If you see their documentation, it says that it needs your package name to start with create-, and should have a script listed in bin to execute the necessary setup process.

I already have a Github project called create-react-ts-starter which a template project I use to start my React projects with TypeScript. This project is written from scratch and includes all necessary webpack configuration along with other additions such as Jest and React Testing Library for testing, Storybook for a component library, Prettier for formatting, ESLint for linting, and husky to enable pre-commit git hook to perform formatting and linting. The project is also hooked up with Vercel for instant deployments. However, since this is a template project and not an npm starter command yet, I am going to do this now.

I have this code repository available in my IDE locally. To start, in my package.json, I will remove the private entry since I am going to make this package public on npm. Then, I will add a bin key and give a path to a script called cli that I will create next. I will create cli.js under bin directory.

I will first add the environment to be node since I will write the nodejs code for my script. I want to provide the name of the repository from the command-line which is captured by process.argv array. The way command would run, the repository name will be received on index = 2. Next, I will create a constant which contains the git checkout command for my Github template repository followed by the name of the repository I provide on the command-line. Next, I will add another constant which contains the command to enter the new repository and runs npm install. I will also print the helpful debug message on the console so that progress is visible to the callers of the command.

Now, we need a way to run these commands. For that, I will create a new function called runCommand. This function will take command and do something with it. In order to run the bash commands from node, I will import a function called execSync from child_process. As the name implies, it will run the command and wait for it to complete. This command may throw errors, so I will run this in a try/catch block. I will pass in the command, and in the options object, I pass in stdio to be inherit. This will print the bash command output as it runs. In the catch block, I take the exception in variable e and print a helpful message on the console. I also return from the function returning false as the value indicating that command execution failed. If the command succeeds, I return true as a value to the caller.

Back to where I started, I will call runCommand and pass gitCheckoutCommand as the argument. The result of this operation is stored in checkedOut variable. If the command does not succeed, I quit the process since there is no benefit in moving forward. Otherwise, I print the next step to be taken on the console and call runCommand with installDepsCommand. Based on the return value, we either quit the process if the command fails, or move forward with a greeting message.

I will also print the next command that caller must take to start the development server. Great! This is the simplest script and could be enhanced further based on your needs, but you get the idea.

Now, back in out package.json, I will add a scope, called h2_demo , which is one of my organizations on npm registry. I want this package to be published under that organization. I also changed the name of the package a little bit. I made a type in the file path so let me fix that now. Also, currently husky is not installed globally, so I will prepend my husky command with npx. And with that I am ready to publish.

On the command-line, I will run npm publish --access=public, and hit enter. The command failed. Oh! it's because I did not add @ symbol in my scope. I will add that and re-run the command. This will compress and send the artifacts to npm registry. Once published, we will see a message on the console. Great! Let's try to use that to create a new project.

On the terminal I will call npx followed by the package name followed by the new project name I want. It asks whether I want to proceed. This is a new change in npm version 7 where all callers must agree to this prompt. Alternatively you can pass -y flag to continue without prompt. I will hit y, and we can follow the logs, I prints the message, and installing the dependencies from the project. Once finished, we see the greeting and the next command to follow. As I copy-paste and hit enter, our project starts, and we can see the output on the webpage. Back on the npm profile page, as I hit refresh, we can see the new package here.

Fantastic! I hope that now you know how to create your own starter commands that could be run with npx. See you next time.