Create React App Template System: How to Build and Use Custom Templates
Create React App generates new projects by resolving the --template flag to an npm package, local path, or tarball, then copying files from the template's template/ directory and merging configurations from template.json into the generated project.
The Create React App template system allows developers to scaffold React projects with custom boilerplate, dependencies, and configurations without maintaining a fork of the toolchain. By creating reusable template packages, teams can standardize project setup across organizations while leveraging the official react-scripts build pipeline. This guide explains the template resolution architecture and provides a step-by-step method for building custom templates.
How the Create React App Template System Works
Template Resolution and CLI Parsing
When you execute npx create-react-app my-app --template <template>, the CLI resolves the template identifier in packages/create-react-app/createReactApp.js. The resolution logic (lines 144-152) accepts three formats:
- npm package names (e.g.,
cra-template-typescript) - Local file paths using the
file:protocol (e.g.,file:../my-template) - Remote tarballs via URL (e.g.,
https://example.com/template.tgz)
The CLI also verifies version compatibility in createReactApp.js (lines 66-72), ensuring the installed react-scripts is version 3.3.0 or higher before attempting template initialization.
Template Initialization and File Copying
Once resolved, the initialization logic in packages/react-scripts/scripts/init.js orchestrates the project generation:
- Locates the template directory (lines 33-40) by searching for a
template/folder within the resolved package - Copies all files from
template/to the new project root recursively - Parses
template.jsonto extract additional metadata under thepackagekey - Merges dependencies (lines 301-307), installing any
dependenciesordevDependenciesspecified intemplate.jsonvia npm or yarn
Anatomy of a Template Package
A valid CRA template is an npm package containing a template/ directory and an optional template.json configuration file.
The template/ Directory
This folder mirrors the structure of a standard CRA project. When users run create-react-app, every file inside template/ is copied to the generated project root. A typical structure includes:
template/
├── public/
│ └── index.html
├── src/
│ ├── App.js
│ ├── App.css
│ └── index.js
└── README.md
The template.json Configuration
Located at the package root, this file defines additional project metadata under a package key. According to the default cra-template implementation in packages/cra-template/template.json, you can specify:
{
"package": {
"dependencies": {
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.1.0",
"web-vitals": "^2.1.0"
},
"eslintConfig": {
"extends": ["react-app", "react-app/jest"]
}
}
}
Dependencies listed here are automatically installed after the template files are copied.
How to Create a Custom Template
1. Initialize the Package Structure
Create a new directory and initialize npm:
mkdir my-cra-template
cd my-cra-template
npm init -y
Update package.json to follow the cra-template-* naming convention (this allows users to reference your template by short name):
{
"name": "cra-template-awesome",
"version": "0.1.0",
"main": "index.js",
"files": [
"template",
"template.json"
]
}
2. Create the Template Directory
Add a template/ folder containing your boilerplate files:
mkdir -p template/src template/public
touch template/README.md
Populate these files with your desired starting structure. For example, template/src/App.js:
import React from 'react';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<h1>Welcome to Awesome Template</h1>
</header>
</div>
);
}
export default App;
3. Configure template.json
If your template requires additional dependencies, create a template.json at the package root:
{
"package": {
"dependencies": {
"axios": "^1.6.0",
"styled-components": "^6.1.0"
},
"scripts": {
"lint": "eslint src/"
}
}
}
4. Test Locally
Before publishing, verify your template works using the file: protocol:
npx create-react-app test-app --template file:./my-cra-template
Check that files are copied correctly and dependencies are installed.
5. Publish to npm
Once validated, publish your template:
npm publish
Users can now scaffold projects with your template:
npx create-react-app my-app --template awesome
Key Source Files in the CRA Codebase
Understanding the implementation helps debug template issues:
-
packages/create-react-app/createReactApp.js– Parses the--templateflag, resolves package names vs. local paths vs. tarballs, and validatesreact-scriptsversion compatibility (lines 66-72 and 144-152). -
packages/react-scripts/scripts/init.js– Executes template initialization: locates thetemplate/directory, copies files recursively, mergestemplate.jsonconfigurations, and installs additional dependencies (lines 33-40 and 301-307). -
packages/cra-template/– Reference implementation of the default JavaScript template, demonstrating the requiredtemplate/structure andtemplate.jsonschema. -
packages/cra-template-typescript/– TypeScript template implementation showing how to include type definitions and compiler configurations.
Summary
- Create React App generates projects by copying files from a template package specified via the
--templateflag. - The CLI resolves templates as npm packages, local
file:paths, or remote tarballs increateReactApp.js(lines 144-152). - Valid templates require a
template/directory containing boilerplate files and an optionaltemplate.jsonfor dependency management. - The initialization script in
init.js(lines 33-40, 301-307) handles file copying, JSON merging, and dependency installation. - Custom templates should follow the
cra-template-*naming convention and can be published to npm or used locally via thefile:protocol.
Frequently Asked Questions
What is the default template used by Create React App?
If you do not specify a --template flag, Create React App defaults to cra-template, which is the standard JavaScript template maintained in the official repository. This template includes a basic React setup with testing libraries and web vitals support, defined in its template.json configuration.
Can I use a local folder as a template without publishing to npm?
Yes. You can reference a local template using the file: protocol when running the create command. For example: npx create-react-app my-app --template file:../path/to/my-template. The CLI resolves this path in createReactApp.js and installs the template locally before copying files.
How do I add extra dependencies to my custom template?
Define additional dependencies inside a package key in your template.json file at the root of your template package. When react-scripts/scripts/init.js processes your template, it automatically merges these dependencies and devDependencies into the generated project's package.json and installs them via npm or yarn.
Why does my template require react-scripts 3.3.0 or higher?
Template support was introduced in react-scripts version 3.3.0. The CLI checks for this version in createReactApp.js (lines 66-72) before attempting to install and initialize a template. If you are using an older version of react-scripts, the --template flag will not function correctly.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →