# Create React App — User Guide

Create React App (CRA) is a toolchain for building single-page React applications with zero build configuration. It sets up a modern development environment with Webpack 5, Babel 7, ESLint, Jest, and a development server so you can focus on writing React code rather than wiring together build tools. CRA generates a project scaffold with sensible defaults and provides four core scripts (`start`, `test`, `build`, `eject`) that cover the full development lifecycle.

> [!CAUTION]
> **Create React App is officially deprecated.** The project maintainers have marked CRA as deprecated and recommend visiting [react.dev](https://react.dev) for modern alternatives such as Next.js, Remix, Gatsby, or Vite-based setups. This guide documents CRA 5.1.0 as-is because millions of existing projects still depend on it. If you are starting a brand-new project, evaluate the alternatives first.

This guide covers **create-react-app 5.1.0** and **react-scripts 5.1.0**, the final release versions. Written from commit `6254386` (2025-02-14) of the source repository.

---

## 1. Quick Start

### 1.1 Create a New Project

The fastest path to a running React app:

```bash
npx create-react-app my-app
cd my-app
npm start
```

Expected output after `npx create-react-app my-app`:

```text
Creating a new React app in /path/to/my-app.

Installing packages. This might take a couple of minutes.
Installing react, react-dom, and react-scripts with cra-template...

...

Success! Created my-app at /path/to/my-app
Inside that directory, you can run several commands:

  npm start
    Starts the development server.

  npm run build
    Bundles the app into static files for production.

  npm test
    Starts the test runner.

  npm run eject
    Removes this tool and copies build dependencies, configuration files
    and scripts into the app directory. If you do this, you can't go back!

We suggest that you begin by typing:

  cd my-app
  npm start

Happy hacking!
```

After `npm start`, open [http://localhost:3000](http://localhost:3000) in your browser to see the running app. The page reloads automatically when you edit source files.

### 1.2 Create a TypeScript Project

```bash
npx create-react-app my-app --template typescript
cd my-app
npm start
```

This scaffolds the project with `.tsx` files, a `tsconfig.json`, and TypeScript type definitions pre-installed.

### 1.3 What You Get

A freshly created project contains:

```text
my-app/
  node_modules/
  public/
    index.html
    favicon.ico
    manifest.json
    robots.txt
  src/
    App.css
    App.js (or App.tsx)
    App.test.js (or App.test.tsx)
    index.css
    index.js (or index.tsx)
    logo.svg
    reportWebVitals.js (or .ts)
    setupTests.js (or .ts)
  .gitignore
  package.json
  README.md
```

> [!NOTE]
> The `public/` directory contains static assets that are served as-is. The `src/` directory is where all your application code lives. Webpack only processes files inside `src/`, so all JS/TS imports must originate there.

---

## 2. Installation

### 2.1 System Requirements

| Requirement | Minimum Version |
|---|---|
| Node.js | 14 or higher |
| npm | 6 or higher |

Verify your versions:

```bash
node --version
npm --version
```

Expected output (example):

```text
v18.19.0
9.2.0
```

### 2.2 Installation Methods

**Using npx (recommended — always runs the latest version):**

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

**Using npm global install:**

```bash
npm install -g create-react-app
create-react-app my-app
```

**Using Yarn:**

```bash
yarn create react-app my-app
```

> [!IMPORTANT]
> If you previously installed `create-react-app` globally via `npm install -g create-react-app`, uninstall it with `npm uninstall -g create-react-app` to ensure `npx` always uses the latest version. Stale global installs can cause unexpected behavior.

### 2.3 Package Manager Detection

CRA automatically detects which package manager you are using. If the `npm_config_user_agent` environment variable contains `"yarn"`, CRA uses Yarn for dependency installation. Otherwise, it defaults to npm.

### 2.4 CLI Options

The `create-react-app` command accepts the following options:

| Option | Description |
|---|---|
| `--verbose` | Print additional logging output during installation |
| `--info` | Print environment debugging information (Node, npm, OS versions) |
| `--scripts-version <version>` | Use a custom or alternative version of `react-scripts` |
| `--template <name-or-path>` | Specify a project template (default: `cra-template`) |
| `--use-pnp` | Enable Yarn Plug'n'Play mode for zero-install dependencies |

**Print environment info:**

```bash
npx create-react-app --info
```

Expected output:

```text
Environment Info:

  current version of create-react-app: 5.1.0
  running from /path/to/create-react-app

  System:
    OS: macOS 14.2
    CPU: (10) arm64 Apple M1 Pro
  Binaries:
    Node: 18.19.0
    npm: 9.2.0
    Yarn: 1.22.19
  Browsers:
    Chrome: 120.0
    Firefox: 121.0
    Safari: 17.2
```

**Use a custom template:**

```bash
npx create-react-app my-app --template typescript
npx create-react-app my-app --template cra-template-pwa
```

**Use verbose output for debugging install failures:**

```bash
npx create-react-app my-app --verbose
```

### 2.5 Available Templates

CRA ships two official templates:

| Template | Package Name | Description |
|---|---|---|
| Default (JavaScript) | `cra-template` | Standard JavaScript project with React 18 |
| TypeScript | `cra-template-typescript` | TypeScript project with `tsconfig.json` and `.tsx` files |

Community templates follow the naming convention `cra-template-*`. You can specify any npm package name or a local file path:

```bash
npx create-react-app my-app --template file:../my-custom-template
```

### 2.6 Updating react-scripts

To update an existing project to a newer version of `react-scripts`:

```bash
npm install react-scripts@latest
```

Check the [react-scripts changelog](https://github.com/facebook/create-react-app/blob/main/CHANGELOG.md) for breaking changes before upgrading.

---

## 3. Configuration

CRA is designed to work with zero configuration. However, it provides extensive customization through **environment variables**, **.env files**, **browserslist**, **proxy configuration**, and **PostCSS/Tailwind** integration — all without ejecting.

### 3.1 Environment Variables

#### 3.1.1 Custom Environment Variables

Any environment variable prefixed with `REACT_APP_` is automatically embedded into your application at build time via Webpack's `DefinePlugin`. Access them in code through `process.env`:

```javascript
// In your React code
const apiUrl = process.env.REACT_APP_API_URL;
const version = process.env.REACT_APP_VERSION;
```

In `public/index.html`, reference them with `%VARIABLE_NAME%`:

```html
<title>%REACT_APP_SITE_TITLE%</title>
```

> [!WARNING]
> Environment variables are **embedded at build time**, not at runtime. After running `npm run build`, the values are baked into the static bundle. Changing a `.env` file requires a rebuild to take effect. Never store secrets in `REACT_APP_*` variables — they will be visible in the client-side JavaScript bundle.

#### 3.1.2 Built-in Environment Variables

CRA recognizes the following built-in environment variables that control development server behavior and build output:

| Variable | Default | Description |
|---|---|---|
| `NODE_ENV` | (auto) | Set automatically: `development` for `start`, `test` for `test`, `production` for `build` |
| `PORT` | `3000` | Port for the development server |
| `HOST` | `0.0.0.0` | Host binding for the development server |
| `HTTPS` | `false` | Set to `true` to run the dev server over HTTPS |
| `SSL_CRT_FILE` | (none) | Path to a custom SSL certificate file (used with `HTTPS=true`) |
| `SSL_KEY_FILE` | (none) | Path to a custom SSL key file (used with `HTTPS=true`) |
| `BROWSER` | (system default) | Browser to open on `npm start`. Set to `none` to disable auto-open |
| `PUBLIC_URL` | `/` | URL prefix for assets. Use when hosting from a subdirectory |
| `BUILD_PATH` | `build` | Output directory for `npm run build` |
| `GENERATE_SOURCEMAP` | `true` | Set to `false` to skip source map generation in production builds |
| `INLINE_RUNTIME_CHUNK` | `true` | Set to `false` to prevent inlining the Webpack runtime chunk |
| `IMAGE_INLINE_SIZE_LIMIT` | `10000` | Images smaller than this (in bytes) are inlined as data URIs |
| `FAST_REFRESH` | `true` | Enable/disable React Fast Refresh in development |
| `DISABLE_ESLINT_PLUGIN` | `false` | Set to `true` to completely disable the ESLint webpack plugin |
| `TSC_COMPILE_ON_ERROR` | `false` | Set to `true` to allow building even when TypeScript type errors exist |
| `ESLINT_NO_DEV_ERRORS` | `false` | Set to `true` to downgrade ESLint errors to warnings in development |
| `NODE_PATH` | (none) | Additional directories to resolve modules from (colon-separated) |
| `WDS_SOCKET_HOST` | (auto) | WebSocket host for the dev server hot-reload connection |
| `WDS_SOCKET_PATH` | (auto) | WebSocket path for the dev server hot-reload connection |
| `WDS_SOCKET_PORT` | (auto) | WebSocket port for the dev server hot-reload connection |
| `DANGEROUSLY_DISABLE_HOST_CHECK` | `false` | Disables the host check on the dev server (security risk) |

#### 3.1.3 Setting Environment Variables

**On the command line (Linux/macOS):**

```bash
PORT=4000 BROWSER=none npm start
```

**On the command line (Windows cmd):**

```bash
set PORT=4000 && set BROWSER=none && npm start
```

**On the command line (Windows PowerShell):**

```powershell
$env:PORT=4000; $env:BROWSER="none"; npm start
```

> [!TIP]
> Use the `cross-env` package for cross-platform environment variable setting in `package.json` scripts: `"start": "cross-env PORT=4000 react-scripts start"`.

### 3.2 .env Files

CRA supports `.env` files for defining environment variables declaratively. Files are loaded in the following priority order (highest to lowest):

1. `.env.{NODE_ENV}.local` — Local overrides for a specific environment
2. `.env.local` — Local overrides (loaded in all environments **except** `test`)
3. `.env.{NODE_ENV}` — Environment-specific defaults
4. `.env` — Global defaults

Where `{NODE_ENV}` is `development`, `test`, or `production`.

**Example `.env` file:**

```text
REACT_APP_API_URL=https://api.example.com
REACT_APP_VERSION=1.2.3
REACT_APP_FEATURE_FLAG=true
```

**Example `.env.development`:**

```text
REACT_APP_API_URL=http://localhost:8080
REACT_APP_DEBUG=true
```

**Example `.env.production`:**

```text
REACT_APP_API_URL=https://api.production.com
REACT_APP_SENTRY_DSN=https://[email removed]/12345
```

> [!NOTE]
> Variables defined in higher-priority files override those in lower-priority files. A variable set in `.env.development.local` overrides the same variable in `.env`. The `.env.local` file is automatically added to `.gitignore` in new CRA projects — use it for machine-specific overrides you don't want committed.

**Variable expansion** is supported within `.env` files:

```text
REACT_APP_DOMAIN=example.com
REACT_APP_API_URL=https://api.$REACT_APP_DOMAIN/v1
```

### 3.3 Browserslist

CRA uses the **browserslist** configuration in `package.json` to determine which browsers to target for CSS autoprefixing and JavaScript transpilation:

```json
{
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}
```

The `production` list controls which transforms Babel applies and which CSS vendor prefixes PostCSS adds. The `development` list keeps the dev bundle lighter by targeting only modern browsers.

### 3.4 HTTPS in Development

Run the development server over HTTPS with a self-signed certificate:

```bash
HTTPS=true npm start
```

Your browser will warn about the untrusted certificate. To use a custom trusted certificate:

```bash
HTTPS=true SSL_CRT_FILE=./certs/server.crt SSL_KEY_FILE=./certs/server.key npm start
```

This is useful when working with APIs that enforce secure contexts or when testing service workers locally.

### 3.5 Proxy Configuration

#### 3.5.1 Simple Proxy

For forwarding API requests to a backend during development, add a `proxy` field to `package.json`:

```json
{
  "proxy": "http://localhost:4000"
}
```

Any request to a path not served by the dev server (i.e., not a static file) will be proxied to `http://localhost:4000`. For example, `fetch('/api/users')` in your code will be proxied to `http://localhost:4000/api/users`.

#### 3.5.2 Advanced Proxy with setupProxy.js

For more control, create `src/setupProxy.js`:

```javascript
const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
  app.use(
    '/api',
    createProxyMiddleware({
      target: 'http://localhost:4000',
      changeOrigin: true,
    })
  );
  app.use(
    '/ws',
    createProxyMiddleware({
      target: 'ws://localhost:4001',
      ws: true,
    })
  );
};
```

> [!IMPORTANT]
> The `src/setupProxy.js` file is only used during development. It is **not** included in the production build. You must configure your production server's reverse proxy separately. The file must use `require()` syntax (CommonJS), not ES module `import`.

### 3.6 Absolute Imports

Configure absolute imports by setting `baseUrl` in `jsconfig.json` (JavaScript) or `tsconfig.json` (TypeScript):

**`jsconfig.json`:**

```json
{
  "compilerOptions": {
    "baseUrl": "src"
  }
}
```

Now you can import from `src/` without relative paths:

```javascript
// Instead of: import Button from '../../../components/Button';
import Button from 'components/Button';
```

### 3.7 Tailwind CSS

CRA supports **Tailwind CSS** natively. If a `tailwind.config.js` file exists at the project root, CRA's PostCSS pipeline automatically includes the Tailwind plugin.

1. Install Tailwind:

```bash
npm install -D tailwindcss
npx tailwindcss init
```

2. Configure `tailwind.config.js`:

```javascript
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./src/**/*.{js,jsx,ts,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
};
```

3. Add Tailwind directives to `src/index.css`:

```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

### 3.8 PostCSS and Autoprefixer

CRA includes **PostCSS** with **autoprefixer** by default. Vendor prefixes are automatically added based on your `browserslist` configuration. No additional setup is needed. For example, if you write:

```css
.container {
  display: flex;
  user-select: none;
}
```

The output CSS will include the necessary vendor prefixes for your target browsers automatically.

---

## 4. Core Usage

### 4.1 The Four Scripts

Every CRA project comes with four scripts defined in `package.json`. These are provided by `react-scripts` and cover the entire development lifecycle.

#### 4.1.1 npm start — Development Server

```bash
npm start
```

Launches a development server at `http://localhost:3000` with:

- **Hot Module Replacement** via React Fast Refresh — edits to React components update in the browser without losing component state
- **ESLint overlay** — lint errors and warnings appear directly in the browser
- **Error overlay** via **react-error-overlay** — runtime errors display a full-screen overlay with the stack trace, clickable to open the source in your editor
- **Automatic browser opening** — your default browser opens to the app URL

Expected terminal output:

```text
Compiled successfully!

You can now view my-app in the browser.

  Local:            http://localhost:3000
  On Your Network:  http://192.168.1.100:3000

Note that the development build is not optimized.
To create a production build, use npm run build.

webpack compiled successfully
```

To change the port:

```bash
PORT=4000 npm start
```

To prevent the browser from auto-opening:

```bash
BROWSER=none npm start
```

#### 4.1.2 npm test — Test Runner

```bash
npm test
```

Launches **Jest** in interactive **watch mode**. By default, it only runs tests related to files changed since the last commit, making the feedback loop fast.

Expected terminal output:

```text
No tests found related to files changed since last commit.
Press `a` to run all tests, or run Jest with `--watchAll`.

Watch Usage
 › Press a to run all tests.
 › Press f to run only failed tests.
 › Press q to quit watch mode.
 › Press p to filter by a filename regex pattern.
 › Press t to filter by a test name regex pattern.
 › Press Enter to trigger a test run.
```

CRA's test setup includes:

- **@testing-library/react** — the recommended library for testing React components
- **jest-dom** matchers — via `src/setupTests.js` which imports `@testing-library/jest-dom`
- **jsdom** environment — tests run in a simulated browser environment

**Example test file** (`src/App.test.js`):

```javascript
import { render, screen } from '@testing-library/react';
import App from './App';

test('renders learn react link', () => {
  render(<App />);
  const linkElement = screen.getByText(/learn react/i);
  expect(linkElement).toBeInTheDocument();
});
```

**Running tests in CI** (non-interactive mode):

```bash
CI=true npm test
```

In CI mode, Jest runs all tests once without watch mode and exits with a non-zero code if any test fails.

**Running with coverage:**

```bash
CI=true npm test -- --coverage
```

This generates a coverage report in the `coverage/` directory.

> [!TIP]
> The `src/setupTests.js` file runs before every test. Use it to configure global test utilities, mock browser APIs, or import custom matchers. CRA scaffolds it with `import '@testing-library/jest-dom';` by default.

#### 4.1.3 npm run build — Production Build

```bash
npm run build
```

Creates an optimized production build in the `build/` directory (configurable via `BUILD_PATH`). The build process:

- Minifies JavaScript and CSS
- Generates content-hashed filenames for long-term caching (e.g., `main.a1b2c3d4.js`)
- Inlines small images as data URIs (below `IMAGE_INLINE_SIZE_LIMIT`, default 10KB)
- Generates source maps (unless `GENERATE_SOURCEMAP=false`)
- Produces a `build/asset-manifest.json` listing all generated files

Expected terminal output:

```text
Creating an optimized production build...
Compiled successfully.

File sizes after gzip:

  46.61 kB  build/static/js/main.a1b2c3d4.js
  1.78 kB   build/static/js/787.f4c22a95.chunk.js
  541 B     build/static/css/main.073c9b0a.css

The project was built assuming it is hosted at /.
You can control this with the homepage field in your package.json.

The build folder is ready to be deployed.
You may serve it with a static server:

  serve -s build

Find out more about deployment at https://cra.link/deployment
```

**Customizing the build output directory:**

```bash
BUILD_PATH=dist npm run build
```

**Skipping source maps (reduces build size and hides source code):**

```bash
GENERATE_SOURCEMAP=false npm run build
```

**Deploying to a subdirectory** (e.g., `https://example.com/my-app/`):

Set `homepage` in `package.json`:

```json
{
  "homepage": "https://example.com/my-app"
}
```

Or use the `PUBLIC_URL` environment variable:

```bash
PUBLIC_URL=/my-app npm run build
```

#### 4.1.4 npm run eject — Eject Configuration

```bash
npm run eject
```

> [!CAUTION]
> **Ejecting is a one-way operation.** Once you eject, you cannot go back. This copies all configuration files (Webpack, Babel, ESLint, Jest) and transitive dependencies directly into your project. You become fully responsible for maintaining them. Consider this a last resort — most customizations can be achieved through environment variables, `.env` files, `src/setupProxy.js`, or packages like `craco` and `react-app-rewired` without ejecting.

After ejecting, your project gains:

- `config/` directory with Webpack, Jest, and environment configuration
- `scripts/` directory with `start.js`, `build.js`, and `test.js`
- All hidden dependencies added directly to `package.json`

### 4.2 Supported File Types

CRA's Webpack configuration handles a wide range of file types out of the box:

| File Extension | Handling |
|---|---|
| `.js`, `.jsx` | Babel-transpiled JavaScript with React JSX support |
| `.ts`, `.tsx` | TypeScript compiled with Babel (type-checking via `tsc`) |
| `.mjs` | ES modules (processed by Webpack) |
| `.css` | Standard CSS, injected via `style-loader` in dev, extracted in production |
| `.module.css` | CSS Modules with locally scoped class names |
| `.scss`, `.sass` | Sass/SCSS (requires `sass` package) |
| `.module.scss`, `.module.sass` | CSS Modules with Sass |
| `.svg` | Importable as React component or URL |
| `.json` | Parsed and importable as a JavaScript object |
| `.bmp`, `.gif`, `.jpg`, `.jpeg`, `.png` | Inlined as data URI if below `IMAGE_INLINE_SIZE_LIMIT` (10KB), otherwise emitted as file |
| `.avif` | AVIF images, same inlining behavior as above |

### 4.3 CSS and Styling

#### 4.3.1 Standard CSS

Import CSS files directly in your components:

```javascript
import './App.css';

function App() {
  return <div className="app-container">Hello</div>;
}
```

```css
/* App.css */
.app-container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}
```

#### 4.3.2 CSS Modules

Name your CSS file with `.module.css` to enable locally scoped class names that avoid naming collisions:

```javascript
import styles from './Button.module.css';

function Button() {
  return <button className={styles.primary}>Click me</button>;
}
```

```css
/* Button.module.css */
.primary {
  background-color: #007bff;
  color: white;
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
}
```

At build time, the class name `primary` is transformed to something like `Button_primary__x1y2z` to guarantee uniqueness.

#### 4.3.3 Sass/SCSS

Install the `sass` package to enable Sass support:

```bash
npm install sass
```

Then import `.scss` or `.sass` files:

```javascript
import './App.scss';
```

```scss
// App.scss
$primary-color: #282c34;

.app-container {
  background-color: $primary-color;
  min-height: 100vh;

  .header {
    font-size: 2rem;
    color: white;
  }
}
```

#### 4.3.4 CSS Modules with Sass

Combine CSS Modules and Sass by using the `.module.scss` or `.module.sass` extension:

```javascript
import styles from './Card.module.scss';

function Card({ children }) {
  return <div className={styles.card}>{children}</div>;
}
```

```scss
// Card.module.scss
$border-radius: 8px;
$shadow: 0 2px 8px rgba(0, 0, 0, 0.1);

.card {
  border-radius: $border-radius;
  box-shadow: $shadow;
  padding: 16px;
}
```

### 4.4 Working with Assets

#### 4.4.1 Images

Import images directly. Small images (below `IMAGE_INLINE_SIZE_LIMIT`, default 10,000 bytes) are inlined as data URIs; larger ones are emitted as files with content hashes:

```javascript
import logo from './logo.png';
import icon from './small-icon.png'; // < 10KB, will be inlined

function Header() {
  return (
    <div>
      <img src={logo} alt="Logo" />
      <img src={icon} alt="Icon" />
    </div>
  );
}
```

Supported formats: **BMP**, **GIF**, **JPEG**, **PNG**, **AVIF**.

To change the inlining threshold:

```text
# .env
IMAGE_INLINE_SIZE_LIMIT=5000
```

#### 4.4.2 SVGs

SVGs can be imported two ways:

**As a URL** (standard image import):

```javascript
import logo from './logo.svg';

function App() {
  return <img src={logo} alt="Logo" />;
}
```

**As a React component** (inline SVG with full styling control):

```javascript
import { ReactComponent as Logo } from './logo.svg';

function App() {
  return <Logo className="app-logo" fill="currentColor" />;
}
```

The `ReactComponent` named export uses SVGR under the hood to transform the SVG file into a React component.

> [!TIP]
> Importing SVGs as React components gives you full CSS and prop control over the SVG elements. Use this approach when you need to change colors, sizes, or animate SVG paths dynamically. Use the URL import when you just need a static image.

#### 4.4.3 JSON

JSON files can be imported directly:

```javascript
import config from './config.json';

console.log(config.apiEndpoint);
```

#### 4.4.4 The public/ Directory

Files in the `public/` directory are served at the root URL and are **not processed by Webpack**. Use this for:

- `index.html` — the main HTML template
- `favicon.ico`, `manifest.json`, `robots.txt`
- Assets that need a fixed URL (e.g., `og:image` meta tags)

Reference public assets in HTML using `%PUBLIC_URL%`:

```html
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
```

Reference public assets in JavaScript using `process.env.PUBLIC_URL`:

```javascript
<img src={process.env.PUBLIC_URL + '/images/banner.png'} alt="Banner" />
```

> [!NOTE]
> Files in `public/` are not minified, not content-hashed, and will cause 404 errors if missing at runtime with no compile-time warning. Prefer importing assets through `src/` whenever possible — Webpack provides compile-time errors for missing files, content-hash caching, and size optimization.

### 4.5 TypeScript

#### 4.5.1 Starting with TypeScript

Create a new TypeScript project:

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

This generates a project with `.tsx` source files, a `tsconfig.json`, and all necessary type definitions pre-installed (`@types/react`, `@types/react-dom`, `@types/jest`, `@types/node`).

#### 4.5.2 Adding TypeScript to an Existing Project

1. Install TypeScript and type definitions:

```bash
npm install --save typescript @types/node @types/react @types/react-dom @types/jest
```

2. Rename any file to `.tsx` (or `.ts` for non-JSX files).

3. Restart the development server. CRA automatically generates a `tsconfig.json` if one doesn't exist.

#### 4.5.3 TypeScript Configuration

CRA manages certain `tsconfig.json` fields and will overwrite them on start. You can customize other fields freely:

```json
{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "baseUrl": "src"
  },
  "include": ["src"]
}
```

**Building despite type errors:**

```bash
TSC_COMPILE_ON_ERROR=true npm start
```

This allows the development server to run even when there are TypeScript type errors, showing them as warnings instead of failures.

### 4.6 Flow

CRA supports **Flow** type annotations out of the box. Add a `// @flow` comment at the top of any file:

```javascript
// @flow
import React from 'react';

type Props = {
  name: string,
  age: number,
};

function Greeting({ name, age }: Props) {
  return <p>Hello {name}, you are {age} years old.</p>;
}

export default Greeting;
```

Babel strips Flow annotations during compilation. No additional configuration is required.

---

## 5. Common Tasks

### 5.1 Adding a Router

CRA does not include routing by default. Install React Router:

```bash
npm install react-router-dom
```

```javascript
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';

function App() {
  return (
    <BrowserRouter>
      <nav>
        <Link to="/">Home</Link>
        <Link to="/about">About</Link>
      </nav>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </BrowserRouter>
  );
}
```

When deploying a single-page app with client-side routing, configure your server to serve `index.html` for all routes. Otherwise, direct URL access to `/about` will return a 404.

### 5.2 Adding Global State

**Using React Context (built-in):**

```javascript
import { createContext, useContext, useState } from 'react';

const ThemeContext = createContext();

export function ThemeProvider({ children }) {
  const [theme, setTheme] = useState('light');
  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      {children}
    </ThemeContext.Provider>
  );
}

export function useTheme() {
  return useContext(ThemeContext);
}
```

### 5.3 Code Splitting

CRA supports code splitting via `React.lazy` and `Suspense`:

```javascript
import React, { Suspense, lazy } from 'react';

const Dashboard = lazy(() => import('./pages/Dashboard'));
const Settings = lazy(() => import('./pages/Settings'));

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <Routes>
        <Route path="/dashboard" element={<Dashboard />} />
        <Route path="/settings" element={<Settings />} />
      </Routes>
    </Suspense>
  );
}
```

Each `lazy()` import creates a separate JavaScript chunk that is loaded on demand.

### 5.4 Fetching Data

```javascript
import { useState, useEffect } from 'react';

function UserList() {
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    fetch('/api/users')
      .then(res => {
        if (!res.ok) throw new Error(`HTTP ${res.status}`);
        return res.json();
      })
      .then(data => setUsers(data))
      .catch(err => setError(err.message))
      .finally(() => setLoading(false));
  }, []);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error: {error}</p>;

  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}
```

During development, use the `proxy` field in `package.json` to avoid CORS issues when your API runs on a different port.

### 5.5 Progressive Web App (PWA)

CRA includes **workbox-webpack-plugin** for generating a service worker. To enable offline support:

1. In `src/index.js`, change the service worker registration:

```javascript
// Change this:
serviceWorkerRegistration.unregister();

// To this:
serviceWorkerRegistration.register();
```

2. The service worker caches your app shell and static assets. Subsequent visits load instantly from cache.

> [!WARNING]
> Enabling the service worker means users may see stale content until the new service worker activates (typically on the next page load). During development, always use `unregister()` to avoid caching development builds.

### 5.6 Custom Error Overlay

CRA includes **react-error-overlay**, which displays a full-screen error overlay in development when:

- A JavaScript runtime error occurs
- An unhandled promise rejection happens
- A compilation error exists

The overlay shows the error message, stack trace, and clickable source locations that open the file in your editor. This behavior is automatic in development and is stripped from production builds.

### 5.7 ESLint Configuration

CRA includes **eslint-config-react-app**, which bundles rules from:

- ESLint core rules
- React-specific rules (`eslint-plugin-react`)
- JSX accessibility rules (`eslint-plugin-jsx-a11y`)
- React Hooks rules (`eslint-plugin-react-hooks`)
- Flow type rules (when Flow is used)
- TypeScript rules (when TypeScript is used)

Lint errors appear in the terminal and as a browser overlay during development.

**Disabling ESLint entirely:**

```text
# .env
DISABLE_ESLINT_PLUGIN=true
```

**Downgrading ESLint errors to warnings in development:**

```text
# .env
ESLINT_NO_DEV_ERRORS=true
```

**Extending ESLint rules** in `package.json`:

```json
{
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ],
    "rules": {
      "no-console": "warn",
      "react/prop-types": "error"
    }
  }
}
```

### 5.8 Testing Patterns

#### 5.8.1 Testing User Interactions

```javascript
import { render, screen, fireEvent } from '@testing-library/react';
import Counter from './Counter';

test('increments counter on button click', () => {
  render(<Counter />);
  const button = screen.getByRole('button', { name: /increment/i });
  fireEvent.click(button);
  expect(screen.getByText('Count: 1')).toBeInTheDocument();
});
```

#### 5.8.2 Testing Async Operations

```javascript
import { render, screen, waitFor } from '@testing-library/react';
import UserProfile from './UserProfile';

test('displays user data after loading', async () => {
  render(<UserProfile userId="123" />);
  
  expect(screen.getByText(/loading/i)).toBeInTheDocument();
  
  await waitFor(() => {
    expect(screen.getByText('John Doe')).toBeInTheDocument();
  });
});
```

#### 5.8.3 Mocking API Calls

```javascript
// src/__mocks__/axios.js
export default {
  get: jest.fn(() => Promise.resolve({ data: {} })),
  post: jest.fn(() => Promise.resolve({ data: {} })),
};
```

```javascript
import axios from 'axios';
import { render, screen, waitFor } from '@testing-library/react';
import UserList from './UserList';

jest.mock('axios');

test('fetches and displays users', async () => {
  axios.get.mockResolvedValue({
    data: [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }],
  });

  render(<UserList />);

  await waitFor(() => {
    expect(screen.getByText('Alice')).toBeInTheDocument();
    expect(screen.getByText('Bob')).toBeInTheDocument();
  });
});
```

#### 5.8.4 Snapshot Testing

```javascript
import { render } from '@testing-library/react';
import App from './App';

test('matches snapshot', () => {
  const { container } = render(<App />);
  expect(container).toMatchSnapshot();
});
```

Snapshots are stored in `__snapshots__/` directories. Update them with:

```bash
npm test -- --updateSnapshot
```

#### 5.8.5 Coverage Reports

```bash
CI=true npm test -- --coverage
```

Expected output:

```text
----------|---------|----------|---------|---------|
File      | % Stmts | % Branch | % Funcs | % Lines |
----------|---------|----------|---------|---------|
All files |   85.71 |    66.67 |   83.33 |   85.71 |
 App.js   |     100 |      100 |     100 |     100 |
 utils.js |   71.43 |    33.33 |   66.67 |   71.43 |
----------|---------|----------|---------|---------|
```

### 5.9 Deployment

#### 5.9.1 Static Server

The simplest way to serve a production build:

```bash
npm install -g serve
serve -s build
```

The `-s` flag enables single-page app mode, rewriting all routes to `index.html`.

#### 5.9.2 Deploying to a Subdirectory

Set `homepage` in `package.json`:

```json
{
  "homepage": "https://mysite.com/app"
}
```

This sets `PUBLIC_URL` to `/app`, and all asset paths will be prefixed accordingly.

#### 5.9.3 Deploying to GitHub Pages

1. Install the deployment package:

```bash
npm install --save-dev gh-pages
```

2. Add to `package.json`:

```json
{
  "homepage": "https://<username>.github.io/<repo-name>",
  "scripts": {
    "predeploy": "npm run build",
    "deploy": "gh-pages -d build"
  }
}
```

3. Deploy:

```bash
npm run deploy
```

#### 5.9.4 Environment-Specific Builds

```bash
# Production build (default)
npm run build

# Build with a custom API URL
REACT_APP_API_URL=https://staging-api.example.com npm run build

# Build without source maps
GENERATE_SOURCEMAP=false npm run build

# Build to a custom directory
BUILD_PATH=dist npm run build
```

### 5.10 Using Web Workers

CRA does not have built-in Web Worker support in Webpack configuration, but you can use them with a workaround:

```javascript
const worker = new Worker(new URL('./worker.js', import.meta.url));

worker.postMessage({ type: 'START', data: largeDataSet });
worker.onmessage = (event) => {
  console.log('Worker result:', event.data);
};
```

### 5.11 Adding Custom Fonts

**Via CSS imports:**

```css
/* src/index.css */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap');

body {
  font-family: 'Inter', sans-serif;
}
```

**Via local font files:**

```css
/* src/fonts.css */
@font-face {
  font-family: 'CustomFont';
  src: url('./fonts/CustomFont-Regular.woff2') format('woff2'),
       url('./fonts/CustomFont-Regular.woff') format('woff');
  font-weight: normal;
  font-style: normal;
}
```

Place font files in `src/fonts/` so Webpack processes them.

### 5.12 Analyzing Bundle Size

Add the source-map-explorer to inspect what contributes to your bundle:

```bash
npm install --save-dev source-map-explorer
```

Add a script to `package.json`:

```json
{
  "scripts": {
    "analyze": "source-map-explorer 'build/static/js/*.js'"
  }
}
```

Run:

```bash
npm run build
npm run analyze
```

This opens a treemap visualization showing the size contribution of each module.

---

## 6. Troubleshooting

### 6.1 'react-scripts' Is Not Recognized

**Symptom:** Running `npm start` fails with `'react-scripts' is not recognized as an internal or external command` or `command not found: react-scripts`.

**Cause:** The `node_modules` directory is missing or corrupted.

**Fix:**

```bash
rm -rf node_modules
rm package-lock.json
npm install
```

On Windows:

```bash
rmdir /s /q node_modules
del package-lock.json
npm install
```

This issue is tracked in [#17117](https://github.com/facebook/create-react-app/issues/17117).

### 6.2 ERR_OSSL_EVP_UNSUPPORTED on Node 17+

**Symptom:** Build or start fails with `Error: error:0308010C:digital envelope routines::unsupported`.

**Cause:** Node.js 17+ uses OpenSSL 3 which removed support for certain legacy algorithms that Webpack 5 / `react-scripts` depends on.

**Fix (recommended) — set the OpenSSL legacy provider:**

```bash
NODE_OPTIONS=--openssl-legacy-provider npm start
```

Or add it to your `package.json` scripts:

```json
{
  "scripts": {
    "start": "react-scripts start",
    "start:legacy": "NODE_OPTIONS=--openssl-legacy-provider react-scripts start",
    "build:legacy": "NODE_OPTIONS=--openssl-legacy-provider react-scripts build"
  }
}
```

This issue is extensively discussed in [#17216](https://github.com/facebook/create-react-app/issues/17216). The most reliable long-term fix is to use Node 16 or 18 LTS.

> [!TIP]
> Use a Node version manager like `nvm` or `fnm` to easily switch between Node versions per project.

### 6.3 .env Variables Not Working

**Symptom:** Environment variables defined in `.env` files are `undefined` in the app.

**Causes and fixes:**

1. **Missing `REACT_APP_` prefix** — Only variables starting with `REACT_APP_` are injected. `API_URL=...` will not work; use `REACT_APP_API_URL=...`.

2. **Server not restarted** — `.env` files are only read when the dev server starts. After editing `.env`, stop and restart:

```bash
# Stop the server (Ctrl+C), then:
npm start
```

3. **Wrong file loaded** — Check the loading priority. A value in `.env.development.local` overrides `.env`.

4. **Syntax errors** — Each line must be `KEY=value` with no spaces around `=`. No quotes needed unless the value contains spaces.

These issues appear across [#13416](https://github.com/facebook/create-react-app/issues/13416), [#11951](https://github.com/facebook/create-react-app/issues/11951), and [#11954](https://github.com/facebook/create-react-app/issues/11954).

### 6.4 Cannot Find Module 'react-scripts/scripts/...' or interopRequireDefault

**Symptom:** Start or build fails with `Cannot find module` errors referencing internal `react-scripts` paths.

**Cause:** Corrupted `node_modules` or version mismatch between dependencies.

**Fix:**

```bash
rm -rf node_modules
rm package-lock.json
npm cache clean --force
npm install
```

If persisting, verify `react-scripts` is in `dependencies` (not `devDependencies`) in `package.json`:

```json
{
  "dependencies": {
    "react-scripts": "5.1.0"
  }
}
```

Related: [#6398](https://github.com/facebook/create-react-app/issues/6398).

### 6.5 ESLint Cache Constantly Regenerated

**Symptom:** The `.eslintcache` file keeps appearing in your project root, cluttering version control.

**Fix:** Add `.eslintcache` to your `.gitignore`:

```text
# .gitignore
.eslintcache
```

CRA's generated `.gitignore` should already include this, but older projects may not have it. Related: [#10161](https://github.com/facebook/create-react-app/issues/10161).

### 6.6 Build Fails on Netlify / CI Platforms

**Symptom:** `npm run build` fails in CI with errors that do not reproduce locally.

**Common causes:**

1. **Case sensitivity** — Linux CI servers have case-sensitive file systems. `import Header from './header'` fails if the file is `Header.js`. Always match exact casing.

2. **Missing dependencies** — Ensure all dependencies are in `dependencies` (not just `devDependencies`) if they're needed at build time.

3. **Node version mismatch** — Pin your Node version in CI. Add an `.nvmrc` file:

```text
18.19.0
```

Or set the Node version in your CI config. Related: [#17208](https://github.com/facebook/create-react-app/issues/17208).

> [!IMPORTANT]
> CI environments typically set `CI=true` automatically. In this mode, ESLint warnings are treated as errors and will fail the build. Fix all warnings locally, or set `ESLINT_NO_DEV_ERRORS=true` if you need a temporary workaround. Setting `CI=false` in your CI environment disables this behavior but is not recommended.

### 6.7 Optional Chaining / Nullish Coalescing Not Working

**Symptom:** Syntax like `obj?.property` or `value ?? default` causes parse errors.

**Cause:** Older versions of `react-scripts` (pre-4.0) do not include Babel plugins for these operators.

**Fix:** Upgrade to `react-scripts` 4.0 or later:

```bash
npm install react-scripts@5.1.0
```

Related: [#9908](https://github.com/facebook/create-react-app/issues/9908).

### 6.8 Dev Server Occupies Port 3000

**Symptom:** `Something is already running on port 3000` when starting the dev server.

**Fix (use a different port):**

```bash
PORT=3001 npm start
```

**Fix (find and kill the process):**

```bash
# macOS/Linux
lsof -i :3000
kill -9 <PID>

# Windows
netstat -ano | findstr :3000
taskkill /PID <PID> /F
```

### 6.9 Hot Reload Not Working

**Symptom:** Changes to files do not trigger a browser refresh.

**Common causes and fixes:**

1. **File is outside `src/`** — Webpack only watches files inside `src/`. Move the file there.

2. **`FAST_REFRESH=false`** — Check your `.env` files; remove or set `FAST_REFRESH=true`.

3. **File system event limits (Linux):**

```bash
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
```

4. **Network file system** — Webpack's file watcher may not work on mounted drives or Docker volumes. Use polling:

```bash
CHOKIDAR_USEPOLLING=true npm start
```

### 6.10 Memory Issues During Build

**Symptom:** Build crashes with `JavaScript heap out of memory`.

**Fix — increase Node's memory limit:**

```bash
NODE_OPTIONS=--max-old-space-size=4096 npm run build
```

For very large projects, you may need 8192 (8GB).

---

## 7. FAQ

### General

**Q: Is Create React App still maintained?**
A: No. CRA is officially deprecated as of the final 5.1.0 release. The React team recommends using frameworks like Next.js, Remix, or Vite-based setups for new projects. Existing CRA projects continue to work but will not receive new features or security patches to `react-scripts`.

**Q: Can I use React 18 with CRA?**
A: Yes. CRA 5.x supports React 18 out of the box. The default template scaffolds with `ReactDOM.createRoot()` for concurrent features.

**Q: What build tool does CRA use?**
A: CRA uses **Webpack 5** for bundling and **Babel 7** (with `babel-preset-react-app`) for JavaScript/TypeScript transpilation. The development server is **webpack-dev-server**.

**Q: Is CRA a monorepo?**
A: Yes. The CRA source repository is a monorepo managed with **Lerna**. Packages live in `packages/*`, including `create-react-app` (the CLI), `react-scripts` (the build tooling), `babel-preset-react-app`, `eslint-config-react-app`, and others. As an end user, you interact with the `create-react-app` CLI and the `react-scripts` package.

### Configuration

**Q: Can I customize the Webpack config without ejecting?**
A: CRA does not expose the Webpack config directly. Community tools like **CRACO** (`@craco/craco`) and **react-app-rewired** allow you to override Webpack, Babel, and ESLint configuration without ejecting. These are third-party solutions and not officially supported.

**Q: How do I add environment-specific configuration?**
A: Use `.env` files with the `NODE_ENV` suffix: `.env.development`, `.env.production`, `.env.test`. Variables in these files are loaded automatically based on which script you run (`start` = development, `build` = production, `test` = test).

**Q: Can I change the output directory for builds?**
A: Yes. Set the `BUILD_PATH` environment variable:

```bash
BUILD_PATH=dist npm run build
```

**Q: How do I use a different port for the dev server?**
A: Set the `PORT` environment variable:

```bash
PORT=8080 npm start
```

**Q: How do I serve my app from a subdirectory?**
A: Set `homepage` in `package.json` to the full URL or path prefix:

```json
{
  "homepage": "/my-app"
}
```

All asset paths will be prefixed with `/my-app`.

### Styling

**Q: Does CRA support CSS-in-JS libraries?**
A: CRA does not include any CSS-in-JS library by default, but you can install and use any library (styled-components, Emotion, etc.) without additional configuration.

**Q: How do CSS Modules work in CRA?**
A: Name your CSS file with a `.module.css` (or `.module.scss`) extension. Import it and use the exported object for class names. Each class name is locally scoped and uniquely generated at build time to prevent collisions.

**Q: Does CRA include PostCSS?**
A: Yes. CRA includes PostCSS with **autoprefixer** enabled by default. Vendor prefixes are added automatically based on your `browserslist` configuration. If a `tailwind.config.js` exists, the Tailwind PostCSS plugin is also included automatically.

### TypeScript

**Q: Does CRA type-check at build time?**
A: CRA uses Babel to strip TypeScript types during compilation (it does not run `tsc` for compilation). Type errors appear in the terminal and browser overlay during development via a separate type-checking process, but **do not block the build by default**. Set `TSC_COMPILE_ON_ERROR=false` if you want strict type checking to block compilation.

**Q: Can I mix JavaScript and TypeScript files?**
A: Yes. CRA supports `.js`, `.jsx`, `.ts`, and `.tsx` files in the same project. You can incrementally adopt TypeScript by renaming files one at a time.

**Q: Does CRA overwrite my tsconfig.json?**
A: CRA manages certain compiler options that it depends on (like `isolatedModules`, `noEmit`, `jsx`). It will reset these on startup if you change them. Other settings like `strict`, `baseUrl`, and custom paths are yours to configure.

### Testing

**Q: What testing library does CRA include?**
A: CRA includes **Jest** as the test runner and scaffolds projects with **@testing-library/react** and **@testing-library/jest-dom** for component testing.

**Q: How do I run a single test file?**
A: In watch mode, press `p` then type a regex matching the file name. Or run:

```bash
npm test -- --testPathPattern="App.test"
```

**Q: How do I run tests in CI without watch mode?**
A: Set `CI=true`:

```bash
CI=true npm test
```

**Q: Where does CRA look for test files?**
A: Jest finds tests in any of these patterns:
- Files in `__tests__/` directories
- Files ending with `.test.js` or `.test.tsx`
- Files ending with `.spec.js` or `.spec.tsx`

### Build and Deploy

**Q: How large is a typical CRA production build?**
A: A minimal CRA app produces approximately 40-50KB of gzipped JavaScript. The size grows with your application code and dependencies.

**Q: Can I disable source maps in production?**
A: Yes:

```bash
GENERATE_SOURCEMAP=false npm run build
```

This reduces build output size and prevents exposing source code on production servers.

**Q: What is the asset-manifest.json file?**
A: After `npm run build`, CRA generates `build/asset-manifest.json` containing a mapping of logical file names to their content-hashed counterparts. Server-side rendering setups and deployment tools use this to reference the correct file names.

**Q: Does CRA support server-side rendering?**
A: CRA is designed for client-side single-page applications. It does not include server-side rendering. For SSR, consider Next.js or use `ReactDOMServer` with a custom server setup (which requires ejecting or using CRACO).

### Progressive Web App

**Q: Is the service worker enabled by default?**
A: No. New CRA projects call `serviceWorkerRegistration.unregister()` by default. Change this to `serviceWorkerRegistration.register()` to enable offline support.

**Q: What caching strategy does the service worker use?**
A: CRA uses **workbox-webpack-plugin** which generates a precache manifest of your build output. All static assets are cached on first load and served from cache on subsequent visits.

### Ejecting

**Q: Can I undo an eject?**
A: No. Ejecting is irreversible. Once you eject, all configuration files are copied into your project and the `react-scripts` dependency is removed. There is no automated way to reverse this. Use version control to preserve a pre-eject snapshot.

**Q: What files does eject create?**
A: Ejecting creates:
- `config/webpack.config.js` — full Webpack configuration
- `config/webpackDevServer.config.js` — dev server configuration
- `config/jest/` — Jest transform and configuration
- `config/env.js`, `config/paths.js`, `config/modules.js` — environment and path utilities
- `scripts/start.js`, `scripts/build.js`, `scripts/test.js` — the three main scripts

**Q: Are there alternatives to ejecting?**
A: Yes. **CRACO** and **react-app-rewired** allow you to override CRA's Webpack, Babel, and ESLint configuration without ejecting. Environment variables also cover many common customization needs.

For full configuration reference, security considerations, architecture internals, and deployment hardening, see the **Admin Guide**.

---

_Generated May 2026 from facebook/create-react-app at 6254386. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
