# babel-preset-react-app: The Complete Guide to Create React App's Babel Preset

> Discover babel-preset-react-app, the zero-config Babel preset for Create React App. Learn about its features including JSX transformation, TypeScript stripping, and modern JS support for efficient compilation.

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

---

**TLDR:** **babel-preset-react-app** is the official Babel preset that powers JavaScript and TypeScript compilation in Create React App, bundling environment targeting, JSX transformation, TypeScript stripping, and modern JavaScript features into a single, zero-config compilation pipeline.

The `babel-preset-react-app` package serves as the compilation backbone for every Create React App (CRA) project, automatically applied during the build process according to the `facebook/create-react-app` source code. This preset consolidates dozens of Babel plugins and presets into one dependency, ensuring React developers can use modern syntax without configuring individual transformations. Understanding its architecture reveals exactly how JSX, TypeScript, and ES2022+ features become browser-compatible code.

## What is babel-preset-react-app?

At its core, **babel-preset-react-app** is a Node.js package located at `packages/babel-preset-react-app/` in the Create React App repository. The entry point [`index.js`](https://github.com/facebook/create-react-app/blob/main/index.js) forwards options to [`create.js`](https://github.com/facebook/create-react-app/blob/main/create.js), which conditionally assembles the final Babel configuration based on the build environment (`development`, `production`, or `test`). The preset enforces strict environment validation, throwing an error if neither `NODE_ENV` nor `BABEL_ENV` is set, as implemented in [`create.js`](https://github.com/facebook/create-react-app/blob/main/create.js) (lines 57-65).

## Core Babel Transformations Included

The preset applies a layered transformation strategy, combining official Babel presets with specific plugins for React and modern JavaScript features.

### Environment Targeting and Polyfills

The foundation is `@babel/preset-env`, configured in [`create.js`](https://github.com/facebook/create-react-app/blob/main/create.js) (lines 71-89) to target appropriate browser versions and Node.js environments. This preset automatically determines required polyfills and syntax transformations using `core-js@3`, ensuring compatibility without manual browserslist configuration.

### React JSX Transformation

For React components, the preset includes `@babel/preset-react` (lines 90-101), which handles JSX transformation. It supports both the **classic runtime** (transforming JSX into `React.createElement`) and the **automatic runtime** introduced in React 17+, which imports the JSX factory functions automatically. During development, it injects `__self` and component-stack helpers for debugging.

### TypeScript and Flow Support

The preset conditionally enables type system support based on file extensions and options:

- **TypeScript**: When the `typescript` option is true, `@babel/preset-typescript` (line 102) strips TypeScript-only syntax before other transformations run.
- **Flow**: If Flow is enabled and the file is not a TypeScript document (`.tsx?`), `@babel/plugin-transform-flow-strip-types` (lines 11-15) removes Flow annotations.

### Modern JavaScript Syntax Plugins

To support experimental and newer ECMAScript features, [`create.js`](https://github.com/facebook/create-react-app/blob/main/create.js) includes several proposal plugins:

- **Legacy decorators**: `@babel/plugin-proposal-decorators` (lines 41-45) enables the legacy `@decorator` syntax, primarily for TypeScript compatibility.
- **Class properties and private members**: `@babel/plugin-proposal-class-properties`, `@babel/plugin-proposal-private-methods`, and `@babel/plugin-proposal-private-property-in-object` (lines 55-72) transform class fields and private identifiers using *loose* mode for better performance.
- **Numeric separators**: `@babel/plugin-proposal-numeric-separator` (lines 73-75) enables underscores in numeric literals like `1_000`.
- **Optional chaining and nullish coalescing**: `@babel/plugin-proposal-optional-chaining` (lines 104-106) and `@babel/plugin-proposal-nullish-coalescing-operator` (lines 107-109) transform `?.` and `??` operators.

### Build Optimizations

For production efficiency and runtime performance:

- **Transform runtime**: `@babel/plugin-transform-runtime` (lines 77-95) extracts Babel helpers (like async/await regenerators) into `@babel/runtime` imports to avoid code duplication. It respects options for `helpers`, `useESModules`, and `absoluteRuntime` paths.
- **Remove PropTypes**: In production builds only, `babel-plugin-transform-react-remove-prop-types` (lines 97-102) eliminates `prop-types` imports and usages to reduce bundle size.

### Macros and Conditional Overrides

The preset enables compile-time code generation via `babel-plugin-macros` (lines 15-17). Additionally, **overrides** in the configuration handle edge cases:

- A Flow override (lines 111-115) re-applies the Flow strip plugin when Flow is enabled but the file is not TypeScript, preventing conflicts with decorators.
- A TypeScript override (lines 116-124) specifically adds the legacy decorators plugin for `.tsx?` files when TypeScript mode is active.

## Usage and Configuration Examples

While CRA applies this preset automatically, you can use it standalone or customize its behavior via options.

### Default Configuration in Create React App

CRA automatically injects the preset, so no manual configuration is required. The default Babel configuration inside a CRA project effectively resolves to:

```json
{
  "presets": ["react-app"]
}

```

### Standalone Installation

For non-CRA projects, install the preset explicitly:

```bash
npm install --save-dev babel-preset-react-app @babel/core

```

Then configure `.babelrc` or [`babel.config.json`](https://github.com/facebook/create-react-app/blob/main/babel.config.json):

```json
{
  "presets": [
    ["react-app", {
      "flow": true,
      "typescript": false,
      "absoluteRuntime": true
    }]
  ]
}

```

### Enabling Specific Features

To enable TypeScript while disabling Flow:

```json
{
  "presets": [
    ["react-app", { "typescript": true, "flow": false }]
  ]
}

```

To use the React 17+ automatic JSX runtime:

```json
{
  "presets": [
    ["react-app", { "runtime": "automatic" }]
  ]
}

```

## Summary

- **babel-preset-react-app** is the curated Babel configuration powering all Create React App builds, located in `packages/babel-preset-react-app/`.
- It bundles `@babel/preset-env` for browser targeting, `@babel/preset-react` for JSX, and conditional TypeScript/Flow support via [`create.js`](https://github.com/facebook/create-react-app/blob/main/create.js) logic.
- Modern syntax features like class properties, optional chaining, and numeric separators are supported via specific proposal plugins configured in [`create.js`](https://github.com/facebook/create-react-app/blob/main/create.js).
- Production builds automatically strip PropTypes and leverage `@babel/plugin-transform-runtime` (lines 77-95) to optimize helper duplication.
- The preset requires either `NODE_ENV` or `BABEL_ENV` to be set, and supports customization through options like `typescript`, `flow`, and `runtime`.

## Frequently Asked Questions

### Do I need to install babel-preset-react-app manually in a Create React App project?

No. Create React App automatically installs and configures `babel-preset-react-app` as part of its `react-scripts` dependency. You do not need to add it to your [`package.json`](https://github.com/facebook/create-react-app/blob/main/package.json) or create a `.babelrc` file unless you are ejecting or using a custom build setup.

### How does babel-preset-react-app handle TypeScript differently from Babel's standard TypeScript preset?

While it uses `@babel/preset-typescript` under the hood, `babel-preset-react-app` adds specific overrides for TypeScript files (`.tsx?`) that include `@babel/plugin-proposal-decorators` in legacy mode. This ensures decorator syntax works correctly in TypeScript files, which is configured in [`create.js`](https://github.com/facebook/create-react-app/blob/main/create.js) lines 116-124.

### What is the difference between the classic and automatic JSX runtime in this preset?

The **classic** runtime transforms JSX into `React.createElement` calls and requires React to be in scope. The **automatic** runtime (React 17+) transforms JSX into imports from `react/jsx-runtime` automatically, so you don't need to import React. You can switch modes using the `runtime` option: `["react-app", { "runtime": "automatic" }]`.

### Can I use babel-preset-react-app in a project that does not use React?

Technically yes, but it is not recommended. The preset includes React-specific transformations like JSX handling and PropTypes stripping that would be unnecessary overhead in a non-React project. For generic modern JavaScript projects, `@babel/preset-env` alone is more appropriate.