Node.js and NPM CLI (comes with Node.js now) installed on your machine, a GitHub account, a account, familiarity with React.js.

Create React App (CRA) is an awesome project for scaffolding out React.js applications with a webpack/babel transpile pipeline and a lot of decisions made for you so that you as the developer can get to writing code faster, rather than setting up a bunch of configuration.  In most cases the default application scaffold is pretty good, but what about when you want to make sure that every app you generate has a common set of dependencies, or common styles?  

There is a not-well documented option that you can use when creating an app using CRA.  --scripts-version allows you to specify a version of the react-scripts module to use when building out the app, this is where all the logic describing how the app gets scaffolded out lives.  We're going to fork the core react-scripts version and make a few changes so that it's easier for us to create uniformly customized app templates.

This post is based on the workflow highlighted by this AuthO blog post, feel free to check it out as well.

Fork facebook/create-react-app

Make a copy of the create-react-app project in your own GitHub (or other repository host).  Forking the repo in GitHub allows us to pull in changes from the original repository as they are made over time.

Clone the Repo

Clone the repository to your local machine to make your customizations.  The changes we'll want to make generally fall into two camps:

  1. Adding to the compile/transpile pipeline
  2. Modifying the template app

We're going to concentrate on number 2 above, we're pretty happy with the bulk of how CRA works, we just want to be able to scaffold out apps that already have the dependencies we use in all of our tools.  This will save us from having to make these changes manually every time we create a new app.

CRA is a mono-repo with a number of different related packages included in the overall repository, so most of our changes will be concentrated inside only one of the projects, the react-scripts project.

Navigate to the react-scripts project by going to create-react-app/packages/react-scripts.

Update the metadata

In order to publish our custom version, we've got to make a couple of changes to the package.json file for the project.

Changes to package.json

We're changing the name of the package so that we can publish our updated version to NPM.  That way when we want to use it we can reference the published package by name.  We're also updating a couple of the URLs that are stored in package.json to point at our repository rather than the facebook version.

Update dependencies

The default dependency list for a CRA app really just includes react and react-dom and there isn't really an easy way to add more dependencies at scaffold-time.  We're going to modify react-scripts/scripts/init.js to add a block of code to install our custom dependencies.

We like to use the redux-bundler project to manage state in our applications and it would be nice to have that lib installed and ready to go when the app is generated.

Changes to init.js

The code is fairly self-explanatory, but what we're doing is essentially copying how the original code installed react and react-dom if they did not already exist.  Line 201 includes the list of packages we would like to add to the app, we just have 2 for now, but that can change over time as needs change.

Modify the template app/components

We made a fair number of changes to the template app, added routing using the redux-bundler library and wired in the state provider so that is already done when you create the app.  I'm not going to take the time to talk about every customization made here, but we essentially re-organized the template app to match how I would typically organize the source folder of a new app prior to getting started coding.

The template app is located in react-scripts/template and is essentially copied into your new app directory when using CRA, so any changes you make here will be reflected in the newly scaffolded app.

Publish to NPM

By changing the name field of package.json to @corpsmap/corpsmap-react-scripts we're telling the NPM CLI that our package should be published to NPM under the corpsmap organization with the name corpsmap-react-scripts.  

Publish the package using npm publish.

**You do need to have created the organization before-hand, have publish rights to the organization, and have signed into the NPM CLI with your NPM credentials before the publish command will work.

Create the New App

Once our custom react scripts module is published we can create a new app using the updated template and script!

Make sure you have create-react-app installed globally on your machine and then run the following command:

create-react-app <app-name> --scripts-version @corpsmap/corpsmap-react-scripts

Replace <app-name> with whatever you want to call the new app, and if you pushed a copy of react-scripts to your own NPM then update the name of the --scripts-version parameter to point at it.  You can optionally specify a version for the NPM package to use by appending @n.n.n to the end of the NPM package name where n.n.n is the version number you would like to use.