How to make a custom create-react-app template

Feb 18, 2020

I found the create-react-app docs a bit lacking for creating a custom template, so here's a guide

With my next Build Week at Lambda School fast approaching, I've been reflecting back on my previous two Build Week experiences. I read through my notes on what things bothered me, what I wished I had done differently, etc. and decided that I might save myself and my teammates a lot of initial set up time if I created a create-react-app template that we can use instead of waiting around for one person to do all of the set up before everyone else can start working. I also wanted to make it a smoother collaboration experience, so I made sure to include dependencies such as prettier, eslint, husky, and lint-staged so that we can make sure that all of our files will all have consistent syntax and structure with minimal manual editing and checking.

You can install my Build Week create-react-app template by running npx create-react-app PROJECT-NAME --template cra-template-build-week-template in your terminal. Or find it on my GitHub here.

As I was going through the create-react-app docs, I found them to be a bit lacking. Now that I've since figured out how to create a template, they make sense. But for a first timer, I found that there was too much assumed knowledge. It took some internet sleuthing and reading of 2 or 3 other blog posts before I was able to figure it out, so I decided to write my own tutorial to hopefully ease the process for someone else!

Basic file structure

According to the docs, the basic file structure for your template "package" should be as follows:

HTML
my-template-folder/ |-- README.md (for npm) |-- template.json |-- package.json
|-- template/ (MUST be named "template") |-- README.md (for users who will use
your template) |-- gitignore |-- public/ | |-- index.html |-- src/ |-- index.js

Getting started

I found it easiest to start by bootstrapping a create-react-app project by running npx create-react-app template in the root of my my-template-folder. This creates a template folder inside of my-template-folder that contains the bootstrapped react app. This folder MUST be named "template". Run cd template to get inside of the template folder. Get rid of anything you don't want to include in your template, such as the default styling, logo, etc. Add all of the packages and dependencies you want your template to have, as well as any styling, files, and structure you want.

When you're happy with your template, run cd .. to go back to the root directory. Now that you're back in my-template-folder, create a template.json file. Copy all of your dependencies and devDependencies from the template/package.json into this new template.json. Do NOT include any dependencies that come with create-react-app, such as react, react-dom, react-scripts, and react-testing-library). These will automatically be added when you run the command to install your template. Then include any custom scripts that you want in the template.json file as well. When you're done, your template.json file should look something like this:

package.jsonJSON
{
"dependencies": {
"styled-components": "^4.4.1
},
"scripts": {
"custom-start": "npm run start"
}
}

Unfortunately, create-react-app doesn’t support devDependencies, so if you don’t copy them and put them all under the “dependencies” field, they’ll be excluded when someone uses your template. You have to manually put them as devDependencies after your project is bootstrapped.

Now that we have our template.json file all set up, run cd template/ to get back into our template directory. Rename the .gitignore file to just gitignore (without the dot). When the create-react-app template command is run, it looks for a file gitignore without the dot and then adds the dot to it. Weird, but ok.

Still inside the template folder, delete the node_modules, package.json, package-lock.json, yarn.lock, and yarn-error.log. If there is no README.md file inside of template, go ahead and add one. This will be the initial README file whenever someone installs your template, so make sure it is descriptive and informative for other users.

With our template directory all cleaned up, run cd .. to get back into the root directory. Create a package.json in the root. In this file, the value of the "name" field is VERY important: it MUST start with "cra-template-". Remove the "private" field (or set it to false) and add "main": "template.json". You can add other fields that you wish (author, description, keywords, etc), but at minimum this is what your package.json should look like:

package.jsonJSON
{
"name": "cra-template-my-template",
"version": "1.0.0",
"license": "MIT",
"main": "template.json"
}

Your template is ready to be tested!

Testing your template

It's always a good thing to test something out before publishing or deploying. We can test our template locally before publishing it for the world to use. Run npx create-react-app your-app --template file: relative/file/path/my-template-folder to create a project based off of your newly created template. The relative file path must be relative to where you are creating your test project and must be the root of the template/package so that it can see the template.json and package.json files. Test the bootstrapped template and when you're happy with it, let's publish it!

Publishing on npm for public use

Once everything looks good and you've tested your template locally, head on over to npm. Create an account if you don't already have one. In your terminal, run npm login in the root of your template package (in our example, my-template-folder). Login with your npm account credentials and then run npm publish. Easy as pie! Your create-react-app template is now available for public use!

Updating your published package

Say you've since made edits and changes since you first published your template. How do you edit the published package?

One option is to update the version number in the package.json file in the root of the template project (my-template-folder here). Check out the npm docs for deciding on version numbers. With your changes saved and the version number updated, all that's left is to run npm publish in the root of the project and it will update!

Another option is to use npm's terminal commands, which can be found here. These allow you to simultaneously update the version number and create a version commit message without having to manually change the version number in your package.json.