Make Your Own create-react-app Templates
Tags: react, npm
Published: 2019-12-16 00:09:02

Running `npx create-react-app` is probably the most popular way of starting a new React project - however don't you wish if the bootstrapped project uses the folder structure you prefer? or comes with more strict `eslint` rules (or custom ones your team use all the time)? or includes more popular stuff like `prettier` auto-formatting, some UI component library you prefer? With the release of `create-react-app@3.3.0` it's now possible to use a custom template to create new projects:

```bash
npx create-react-app PROJECT_NAME --template my-awesome-template
```

So how do we create & publish our own templates?

## Project Structure

There are some limited [documentation](https://create-react-app.dev/docs/custom-templates/) on the official site - however the official [templates](https://github.com/facebook/create-react-app/tree/master/packages/cra-template) repo offers more clues. 

When we look at the official template repo, we can see there are three major components to a template: 

* `package.json` - this has nothing to do with the `package.json` file we see in a typical react project. This file here defines the template package - A `cra` template is just another `npm` package - once it's published - anyone can use the `create-react-app` cli just by referencing the name of the package. 
* `template.json` - interesting, it seems it's an extension to `package.json` - if we want to include any extra dependencies, we can put them here. 
* `template` - it's the main project folder, this should include all the files we would like to include in the newly bootstrapped project. Notice that there are no `package.json` or `package-lock.json` files here - we should let `create-react-app` handle them. 

Seems pretty straight forward, let's create our own template!

## Setting Up

I would like to start with the `template` folder - the easiest way is to create an empty project with `create-react-app`

```bash
npx create-react-app my-awesome-template
```

Now, let's go to the project folder and add some extra dependencies with `yarn`. 

```bash
cd my-awesome-template
yarn add node-sass @material-ui/core prettier
```

We can edit & re-organize the files in this project, add a `.prettierrc` or `.eslintrc`, change the components, add your own logos, fonts, etc. Go crazy, make it look like the ideal project you want it to be! Don't forget to edit the `README` file as well. 

## Publishing to npm

Now we've got the templates, let's make a new folder which will be the home to our template project:

```bash
mkdir cra-template-my-awesome-template
```

Usually we should use something like `npm init` to create a new `package.json` file for our package, but here let's just copy [the one from the official template](https://github.com/facebook/create-react-app/blob/master/packages/cra-template/package.json)

Open the file in your favorite editor, and make sure to change the following fields:

* `name`: name of the template package. By convention the name of the package should be prefixed with `cra-template-`, however it's not required. The benefit of having that prefix is that the users won't have to type the full name of the package to use it. 
If you need to publish the package under an organization, your users will have to use the fullname of the template, instead of just the part after the prefix. e.g. if the name here is `@acme-inc/cra-template-acme`, the user will have to speicify `--template @acme-inc/cra-template-acme` in the command line.
* `version`: your own version - by default cra will always use the latest version found on npm.
* `description`, `author`, `keywords` : introduce yourself and your template to the world
* `repository`: if you don't have a repo for this, just delete this for now, however we should always check our templates into source control.


Now, create a `template.json` file, and copy the dependencies we installed earlier to this file. If you have some custom scripts, you can add a `scripts` field here as well. Remember not to include anything that usually comes with `create-react-app`.

```json
{
  "dependencies": {
    "@material-ui/core": "^4.8.0",
    "node-sass": "^4.12.0",
    "prettier": "^1.19.1"
  },
  "scripts": {
    "fix-formatting": "prettier --write src/**/*.{js,jsx}"
  }
}
```

At the time of writing, only `dependencies` and `scripts` are supported, everything else will be ignored. Also, if you have `npm run` in your scripts, they will be replaced automatically with `yarn` if your user uses `yarn` to bootstrap their apps. Nice!

Next, let's copy the project we setup previously to the `template` folder. A few notes:

* don't copy `package.json` or `yarn.lock` or `package-lock.json` - we want `create-react-app` cli to manage them
* don't copy `node_modules` or `build` - or anything that you don't want to check into source control.
* rename `.gitignore` to `gitignore` (cra will rename it back)

And it's ready to be shipped to the world! 🚀

```bash
npm publish
```

Don't forget to share your awesome template repo with the world as well - keeping the dependencies up-to-date and fixing bugs ASAP are as important as sharing your awesome ideas with the community.

And we are done! Congrats and happy coding!