# react-app-rewired: editing create-react-app's webpack config without ejecting

> react-app-rewired swaps react-scripts for its own CLI so a config-overrides.js file can edit the webpack, Jest and dev server configs that create-react-app hides. It is a small tool with a narrow window of usefulness, and the README itself points elsewhere.

**timarney/react-app-rewired** — Override create-react-app webpack configs without ejecting

- Repository: https://github.com/timarney/react-app-rewired
- Stars: 9,836 · Forks: 417
- Language: JavaScript
- License: MIT
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/timarney-react-app-rewired

## The problem react-app-rewired solves for create-react-app users

create-react-app ships with no config surface. The webpack configuration lives inside react-scripts, and the official escape hatch is eject, which copies every config file into your project and hands you permanent ownership of them. After that you are on your own for upgrades, because there is no path back. react-app-rewired exists to avoid that trade.

The README states the goal plainly: tweak the create-react-app webpack configs without using eject and without creating a fork of react-scripts. The repository description says the same in one line. So the audience is narrow and specific. You have a project built on react-scripts, you need one loader, plugin or dev server setting that CRA does not expose, and you are not willing to fork the toolchain to get it.

The README is candid about the cost. It warns that by doing this you are breaking the guarantees that CRA provides, that you now own the configs, and that no support will be provided. It quotes Dan Abramov's line, stuff can break. That is not marketing hedging. It is the actual contract of the tool: react-app-rewired gives you reach into internals that CRA deliberately keeps private, and the internals move between releases.

## How the override mechanism works: a bin wrapper and config-overrides.js

The package ships a bin entry, react-app-rewired, which maps to ./bin/index.js. When you flip your npm scripts from react-scripts to react-app-rewired, that binary runs instead of the original command. It loads your config-overrides.js from the project root, applies whatever your exported functions return, and then hands the result to the underlying react-scripts code path.

The default export is a single function. The README shows its signature as override(config, env), receiving the webpack config object and the environment, and returning the config. Whatever you mutate or add is what gets compiled.

There is a second, richer form. Instead of a function you can export an object with up to three fields, each a function: webpack, jest, and devServer. The README explains why jest appears separately: the normal rewires do not work for the Jest config. The devServer field is different again. It does not receive a config object but a configFunction, and you return a replacement function that create-react-app will call with the proxy and allowedHost parameters. The README's example calls configFunction(proxy, allowedHost) to get the default config and then modifies it, rather than building one from scratch. That detail matters, because it means you inherit CRA's defaults and only change what you name.

The package has one runtime dependency, semver, and declares react-scripts >=2.1.3 as a peer dependency. There is no plugin registry, no CLI flags for the override itself, and no configuration file format beyond JavaScript.

## Installing react-app-rewired and running a first build

The README gives two install commands depending on your react-scripts generation. For create-react-app 2.x with Webpack 4, the command is:

```bash
npm install react-app-rewired --save-dev
```

For create-react-app 1.x or react-scripts-ts with Webpack 3, it pins an older major:

```bash
npm install react-app-rewired@1.6.2 --save-dev
```

The version split is worth reading twice. If you are on CRA 1.x and install the current package, the peer dependency on react-scripts >=2.1.3 is not what you have.

Next, create config-overrides.js in the project root. The README's minimal version returns the config untouched, which is the right starting point because it proves the wiring works before you change anything:

```javascript
/* config-overrides.js */

module.exports = function override(config, env) {
  //do stuff with the webpack config...
  return config;
}
```

Then flip the start, build and test scripts in package.json. The README shows the change as a diff:

```diff
  "scripts": {
-   "start": "react-scripts start",
+   "start": "react-app-rewired start",
-   "build": "react-scripts build",
+   "build": "react-app-rewired build",
-   "test": "react-scripts test",
+   "test": "react-app-rewired test",
    "eject": "react-scripts eject"
}
```

Leave eject alone. The README is explicit: do not flip the eject script, because it runs once and afterwards you have full control of the webpack configuration and no longer need react-app-rewired. There are no configuration options to rewire for eject.

With that in place, npm start runs the dev server and npm run build produces the bundle, both through the rewired path. If you want the override file to live somewhere else, for example a preconfigured one inside node_modules, the README documents a package.json key for it:

```json
"config-overrides-path": "node_modules/some-preconfigured-rewire"
```

## What the README does not promise, and where this tool is the wrong choice

The strongest limitation is stated by the maintainer, not by a critic. The README says that as of Create React App 2.0 the repo is lightly maintained, mostly by the community. The latest release listed is 2.2.1 from 2022-02-15, and the last push to the repository was on 2026-09-13. The gap between the two is the practical warning: the package surface has been stable for years while the toolchain underneath it keeps moving.

That matters because react-app-rewired works by reaching into react-scripts internals. The README does not document a compatibility matrix beyond the peer dependency range, does not describe what happens when react-scripts changes its config shape, and does not document rollback. If an upgrade breaks your override, the failure appears at build or dev server start, in your config-overrides.js, and the README offers no debugging path beyond the note that you own the config.

There is also a scope limit. The override functions receive the webpack config, the Jest config and the dev server factory. They do not give you a general plugin system, and the README's issue guidance makes the boundary blunt: before filing an issue, make sure it is a problem with the code in this repo and not a how do I configure Webpack question. Configuration questions are directed to Stack Overflow or Spectrum. If your real need is a different build system rather than a patch to this one, react-app-rewired is the wrong layer to fix it in.

The README's own author says he personally uses next.js or Razzle, both of which support custom Webpack out of the box. That is about as direct a signal as a project can give about when not to use it.

## react-app-rewired versus craco, Rescripts and customize-cra

The README lists the alternatives itself, and they differ in how much structure they add on top of the same idea.

craco is named as an alternative. The difference in approach is that craco is a separate configuration layer rather than a bin that loads a single override file; you install it and it takes over the scripts, with its own config file conventions. If you want the override logic to be a first-class part of the project rather than a function you export, that is the trade.

Rescripts is described in the README as an alternative framework for extending CRA configurations, supporting 2.0 and later. The word framework is the distinction: react-app-rewired gives you a function that receives a config and returns it, while Rescripts organizes extensions into a structure. More structure means more to learn and more that can fall out of date.

customize-cra is described as a set of CRA 2.0 compatible rewirers. It is not a replacement for react-app-rewired so much as a companion: it provides ready-made override functions you can call from your config-overrides.js instead of writing the webpack manipulation yourself. If you adopt react-app-rewired and find yourself writing the same loader and alias tweaks as everyone else, that is the layer to look at.

react-scripts-rewired is listed as a fork of this project that aims to support CRA 2.0. A fork means a different maintenance owner and a different release cadence, which is a decision about who you trust rather than about API shape. The README does not rank these options, and neither should you treat its list as a ranking.

## Licence, maintenance and the cost of upgrading

The package is MIT licensed, and package.json declares the same. That is permissive: you can use it in commercial and closed-source projects, modify it, and redistribute it, provided the licence text and copyright notice travel with it. This is a description of the licence terms, not legal advice; if your organisation has specific obligations around bundled dependencies, check them against the actual LICENSE file in the repository rather than this summary.

The upgrade cost has two halves. The first is react-scripts itself. Since react-app-rewired declares react-scripts >=2.1.3 as a peer dependency and depends on the shape of the configs react-scripts produces, a react-scripts upgrade is the event most likely to require changes in your config-overrides.js. The README does not publish a supported-versions table, so the check is empirical: upgrade react-scripts, run the build, and see whether the override still applies cleanly.

The second half is the package's own cadence. Releases listed run from 2.1.11 in 2021 through 2.2.0 and 2.2.1 in February 2022, and the README describes the project as lightly maintained. Treat react-app-rewired as a stable, slow-moving shim rather than something that will track new webpack or Jest features for you. Budget for reading the react-scripts source when something breaks, because the README points configuration questions away from the issue tracker.

## Conclusion

Adopt react-app-rewired only if you are on react-scripts 2.x or later and need a small, permanent patch to webpack, Jest or the dev server config. Do not adopt it if you can choose the toolchain freely: the README's own author writes that he uses next.js or Razzle, and lists customize-cra, Rescripts, react-scripts-rewired and craco as alternatives. Before committing, verify that your react-scripts version satisfies the peerDependencies range of >=2.1.3, that your config-overrides.js returns the config object it receives, and that your package.json start, build and test scripts point at react-app-rewired while eject still points at react-scripts.

## FAQ

### What is react-app-rewired?

It is a tool that lets you tweak the create-react-app webpack configs without ejecting and without forking react-scripts. It does this by providing a react-app-rewired binary that loads a config-overrides.js file from your project root and applies your changes. The README warns that you then own the configs and that no support is provided.

### How do I install react-app-rewired?

For create-react-app 2.x with Webpack 4, the README gives npm install react-app-rewired --save-dev. For create-react-app 1.x or react-scripts-ts with Webpack 3, it gives npm install react-app-rewired@1.6.2 --save-dev. After installing, you create config-overrides.js and point the start, build and test scripts at react-app-rewired.

### Why does react-app-rewired say it is not recognized as an internal or external command?

That error means the react-app-rewired binary is not available on your path, which usually follows from the package not being installed in the project. The README's install step is npm install react-app-rewired --save-dev, run in the project directory, after which the bin entry react-app-rewired is available to the npm scripts.

### What is the difference between react-app-rewired and react-scripts?

react-scripts is the create-react-app package that holds the webpack, Jest and dev server configuration. react-app-rewired is a wrapper that runs in its place, loads your config-overrides.js, and passes the modified config through to the react-scripts code path. The README notes that react-scripts >=2.1.3 is a peer dependency.

### What alternatives to react-app-rewired does the project recommend?

The README points to customize-cra for a set of CRA 2.0 compatible rewirers, Rescripts as an alternative framework for extending CRA configurations, react-scripts-rewired as a fork, and craco. It also notes that the author personally uses next.js or Razzle, both of which support custom Webpack out of the box.

## Sources

- [Issues](https://github.com/timarney/react-app-rewired/issues)
- [License: MIT](https://github.com/timarney/react-app-rewired/blob/master/LICENSE)
- [README](https://github.com/timarney/react-app-rewired/blob/master/README.md)
- [Releases](https://github.com/timarney/react-app-rewired/releases)
- [timarney/react-app-rewired on GitHub](https://github.com/timarney/react-app-rewired)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/timarney-react-app-rewired
