# Create React App Template System: How to Build and Use Custom Templates

> Learn to create and use custom Create React App templates. Build your own reusable project structures by leveraging the CRA template system and its template json configuration.

- Repository: [Meta/create-react-app](https://github.com/facebook/create-react-app)
- Tags: how-to-guide
- Published: 2026-02-26

---

**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`](https://github.com/facebook/create-react-app/blob/main/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`](https://github.com/facebook/create-react-app/blob/main/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`](https://github.com/facebook/create-react-app/blob/main/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`](https://github.com/facebook/create-react-app/blob/main/packages/react-scripts/scripts/init.js) orchestrates the project generation:

1. **Locates the template directory** (lines 33-40) by searching for a `template/` folder within the resolved package
2. **Copies all files** from `template/` to the new project root recursively
3. **Parses [`template.json`](https://github.com/facebook/create-react-app/blob/main/template.json)** to extract additional metadata under the `package` key
4. **Merges dependencies** (lines 301-307), installing any `dependencies` or `devDependencies` specified in [`template.json`](https://github.com/facebook/create-react-app/blob/main/template.json) via 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`](https://github.com/facebook/create-react-app/blob/main/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`](https://github.com/facebook/create-react-app/blob/main/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`](https://github.com/facebook/create-react-app/blob/main/packages/cra-template/template.json), you can specify:

```json
{
  "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:

```bash
mkdir my-cra-template
cd my-cra-template
npm init -y

```

Update [`package.json`](https://github.com/facebook/create-react-app/blob/main/package.json) to follow the `cra-template-*` naming convention (this allows users to reference your template by short name):

```json
{
  "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:

```bash
mkdir -p template/src template/public
touch template/README.md

```

Populate these files with your desired starting structure. For example, [`template/src/App.js`](https://github.com/facebook/create-react-app/blob/main/template/src/App.js):

```javascript
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`](https://github.com/facebook/create-react-app/blob/main/template.json) at the package root:

```json
{
  "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:

```bash
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:

```bash
npm publish

```

Users can now scaffold projects with your template:

```bash
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`](https://github.com/facebook/create-react-app/blob/main/packages/create-react-app/createReactApp.js)** – Parses the `--template` flag, resolves package names vs. local paths vs. tarballs, and validates `react-scripts` version compatibility (lines 66-72 and 144-152).

- **[`packages/react-scripts/scripts/init.js`](https://github.com/facebook/create-react-app/blob/main/packages/react-scripts/scripts/init.js)** – Executes template initialization: locates the `template/` directory, copies files recursively, merges [`template.json`](https://github.com/facebook/create-react-app/blob/main/template.json) configurations, and installs additional dependencies (lines 33-40 and 301-307).

- **`packages/cra-template/`** – Reference implementation of the default JavaScript template, demonstrating the required `template/` structure and [`template.json`](https://github.com/facebook/create-react-app/blob/main/template.json) schema.

- **`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 `--template` flag.
- The CLI resolves templates as npm packages, local `file:` paths, or remote tarballs in [`createReactApp.js`](https://github.com/facebook/create-react-app/blob/main/createReactApp.js) (lines 144-152).
- Valid templates require a **`template/`** directory containing boilerplate files and an optional **[`template.json`](https://github.com/facebook/create-react-app/blob/main/template.json)** for dependency management.
- The initialization script in [`init.js`](https://github.com/facebook/create-react-app/blob/main/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 the `file:` 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`](https://github.com/facebook/create-react-app/blob/main/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`](https://github.com/facebook/create-react-app/blob/main/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`](https://github.com/facebook/create-react-app/blob/main/template.json) file at the root of your template package. When [`react-scripts/scripts/init.js`](https://github.com/facebook/create-react-app/blob/main/react-scripts/scripts/init.js) processes your template, it automatically merges these `dependencies` and `devDependencies` into the generated project's [`package.json`](https://github.com/facebook/create-react-app/blob/main/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`](https://github.com/facebook/create-react-app/blob/main/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.