create-react-app: Since updating to 3.3.0, running out of memory

Describe the bug

After upgrading to 3.3.0 and TS 3.7.3 (was previously on 3.2.0 and TS 3.7.2), I am unable to run yarn start

I receive this error: FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

Reverting to react-scripts v3.2.0 resolves this issue - Typescript being at 3.7.3 or 3.7.2. has no effect, so I’ve narrowed it to react-scripts.

Did you try recovering your dependencies?

Yes, blew away node_modules and re-ran yarn, tried without a lock file, etc. No dice.

Environment

Windows 10, VSCode (also occurs on my macbook)

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Reactions: 161
  • Comments: 136 (9 by maintainers)

Commits related to this issue

Most upvoted comments

I had the same error with nodejs v10; upgrading to nodejs v12 fixed the issue for me.

I’ve been able to run app changing npm start script

      "start": "react-scripts --max_old_space_size=4096 start",

Temporary workaround is to set a larger max-old-space-size eg, react-scripts --expose-gc --max-old-space-size=8192 ... as stated in https://github.com/facebook/create-react-app/issues/8130#issue-535323604

Root Problem

Create React App uses fork-ts-checker which creates a new process to handle typescript checking. This thread defaults to 2GB of memory usage. Because this is creating a new process it will not use the max_old_space_size setting!

Related issues

#10102 #8833

Solution

As of CRA v4.0.1 we have no official way of overwriting this.

Solution for v4.0.1 and below using craco

// new file called "craco-fork-ts-checker-plugin.js"

module.exports = {
    overrideWebpackConfig: ({ webpackConfig, cracoConfig, pluginOptions }) => {
        const ForkTsCheckerWebpackPlugin = webpackConfig.plugins.find(
            plugin => plugin.constructor.name === "ForkTsCheckerWebpackPlugin"
        );

        // If we can't find the loader then throw an error.
        if (!ForkTsCheckerWebpackPlugin) {
            throw new Error('could not find ForkTsCheckerWebpackPlugin');
        }

        if (!pluginOptions.memoryLimit) {
            console.log("No memoryLimit option passed in, defaulting to 2048 MB");
        }

        // Loop through each match, increasing memory usage
        ForkTsCheckerWebpackPlugin.memoryLimit = pluginOptions.memoryLimit || 2048;

        // if you want to make sure this is working you can console.log(webpackConfig)

        return webpackConfig;
    }
};
// your craco config-overrides.js file

// import or custom memory modification plugin
const CracoForkTSCheckerPlugin = require('./craco-fork-ts-checker-plugin');

module.exports = {
    plugins: [
        {
            plugin: CracoForkTSCheckerPlugin,
            options: {
                memoryLimit: 6144 // set memory usage in MB, in this example 6GB
            },
        }
    ]
};

CRA v4.1+ (if PR #10004 is accepted) will update the version for fork-ts-checker which now has a option to specify the memory limit via package.json.

 // package.json, add "fork-ts-checker" key to the root object
 "fork-ts-checker": {
	"typescript": {
		"memoryLimit": 6144 // set memory usage in MB, in this example 6GB
	}
 }

Side notes:

Before upping the memory usage you should look into the root performance cause. Follow the debug steps on Typescript Performance and verify you aren’t selecting too many files, have Circular Dependencies, Complex types, etc…

You can run your typescript build outside of react and enable “extendedDiagnostics” via tsc --extendedDiagnostics. Because you are running outside of react you will not be constrained by the 2GB memory limit and your build should eventually complete. Look at “Memory used”, you will notice the build takes 2GB+ (fluctuates a bit based on cache)

In our specific instance we organically reached beyond the 2GB limit due to our project size.

Project Size:

  • 2,000+ tsx react files
  • 1,000+ ts typescript files
  • In total over a half million lines of typescript code. This does not include third-party imported .d.ts files

If your project is smaller than this you should start with optimizing your config instead of upping the memory limit

It looks like this issue: babel/babel#10875. That’s fixed in https://github.com/babel/babel/releases/tag/v7.7.7. create-react-app should bump the @babel/core dependency.

I did some profiling using cpuprofile-webpack-plugin on my project where I have this issue, these are the results

react-scripts 3.2.0

it took 47s to built the project

image

image

react-scripts 3.4.1

it tool 150s to build the same project, 3x slower, and it seems eslint-loader required more resources

image

image

react-scripts 3.4.1 disabling eslint

for this test I disabled eslint then the build took 56s

image

image

https://github.com/xiaoxiangmoe/create-react-app-running-out-of-memory

@ianschmitz

If we change “react-scripts”: “3.3.0” to “react-scripts”: “3.4.0”, the error will disappear.

It is still happening in 3.4.0

+1 I have been getting out of memory errors when running craco start since upgrading to react-scripts@5.0.0

The following in package.json fixed the issue for me (react-scripts 3.3.0, react-pdf) without requiring the memory increase flags:

  "devDependencies": {
    "@babel/core": "^7.7.7",

Same problem here. I upgraded to react-scripts 3.3.0 and webpack 4.41.2 and I had this memory problem.

@petetnt suggestion did not help

Disabling sourcemaps generation solved the problem, but you need them when developing !

@BudickDa what part of temporary fix didn’t you get? Trying to play clever by stating the obvious? I do NOT maintain this codebase, and until they find the software defect that causes this application failure, I have used that configuration setup to avoid it but the thread has become pretty long. Take your hot-takes and ranting somewhere else.

TL;DR: Add this option to the script command --max_old_space_size=4096. Plenty of comments have buried a temporary fix shared by @buncismamen :

I also got the error with new project npx create-react-app and installing plotly adding the memory flag to start scripts fixing the issue

"start": "react-scripts --max_old_space_size=4096 start",

Please, make sure you don’t allocate more RAM than your machine has.

Throwing memory on a memory problem is not a fix.

If max_old_space_size is “fixing” your problem, something is not getting garbage collected which means your code or some package your using is doing some weird stuff. In any case: You need to find and fix the problem!

If you’re using yarn (npm doesn’t support this natively unfortunately) you can use resolutions instead of devDependencies

"resolutions": {
  "@babel/core": "^7.7.7"
}

Using npm with devDependencies might not always work immediately since NPM is non-deterministic and the node_modules tree depends on the order of installation.

I have new react project and I still see this error even after setting max old space size

react-scripts --max_old_space_size=4096 build

I am using react-scripts version 4.0.3 and react version 17.0.2

any update?

This happens again with react-scripts@5.0.0. For me it is caused by: import pdfjsWorker from 'pdfjs-dist/legacy/build/pdf.worker.entry' and can be fixed by deactivating building sourcemaps. It did not occur however on 4.0.3 .

I had a similar issue that was solved by upgrading from node10 to node12. Give that a shot if you’re not already on LTS.

disabling source maps for production build did the trick for me

"scripts": {
   ...
   "cibuild": "CI=true GENERATE_SOURCEMAP=false react-scripts build"
}

downgrading/upgrading package versions made it worse in some cases (more memory needed)

Just confirming that npm update @babel/core --depth 3 fix proposed by @mehrdadgit is working fine on latest version of react-scripts (3.4.1) for me.

--max-old-space-size=8192 is not supported by most of the CI’s and will make the build fail once npm run build start due to memory limitations. We use docker hub for building the frontend images and the limit is 3GB.

Also, build time went from 28 to 10 minutes. It’s a huge improvement!

A bump in @babel/core can simply fix the problem.

I also got the error with new project npx create-react-app and installing plotly

adding the memory flag to start scripts fixing the issue

"start": "react-scripts --max_old_space_size=4096 start",

my package.json

{
  "name": "plot.ly",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.3.2",
    "@testing-library/user-event": "^7.1.2",
    "plotly.js": "^1.52.3",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-plotly.js": "^2.4.0",
    "react-scripts": "3.4.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

Just to clarify. 3.4 the same thing, and it’s supercritical cause it kills our error reporting because we don’t upload source maps 😦

If you don’t want to migrate to yarn or downgrade to react-scripts@3.2.0,

npm update @babel/core --depth 3

fixed the issue for me (Node v12.4.1)

Use @petetnt suggestion is work but it take a lot of build time.

me too

I also encountered the same problem in the company project.

For TypeScript folks out there:

The Problem: I have been facing the same problem for few days now. --max-old-space-size won’t help. since it doesn’t forward the heapLimit to ForkTsCheckerWebpackPlugin

https://github.com/TypeStrong/fork-ts-checker-webpack-plugin/blob/main/README.md#options Default spaceLimit is 2048.

CRA doesn’t send any value for spaceLimit here: https://github.com/facebook/create-react-app/blob/main/packages/react-scripts/config/webpack.config.js#L720

My solution: I already use react-app-rewired along with customize-cra to provide configs for CRA. What I did is to simply find and replace ForkTsCheckerWebpackPlugin plugin as following:

config-overrides.js

const { override, useBabelRc, removeModuleScopePlugin, addWebpackPlugin } = require('customize-cra');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const paths = require("react-scripts/config/paths.js");
const resolve = require('resolve');

module.exports = (config, webpackEnv) => {
  // https://github.com/facebook/create-react-app/blob/main/packages/react-scripts/config/webpack.config.js#L101
  const isEnvDevelopment = webpackEnv === 'development';
  const isEnvProduction = webpackEnv === 'production';
  const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';

  // feel free to find a smarter way to detect and grab the plugin index 🤷‍♂️ 
  const forkTsCheckerWebpackPluginIndex = config.plugins.findIndex(plugin => {
    const  options = plugin.options || {}
    return "async" in options && "typescript" in options && "issue" in options && "logger" in options;
  });


  // copied from: https://github.com/facebook/create-react-app/blob/main/packages/react-scripts/config/webpack.config.js#L720
  // and only increased the memory limit
  const heapSizeLimit = 9000;
  const newTsCheckerWebpackPlugin = new ForkTsCheckerWebpackPlugin({
    async: isEnvDevelopment,
    typescript: {
      memoryLimit: heapSizeLimit,
      typescriptPath: resolve.sync('typescript', {
        basedir: paths.appNodeModules,
      }),
      configOverwrite: {
        compilerOptions: {
          sourceMap: isEnvProduction
            ? shouldUseSourceMap
            : isEnvDevelopment,
          skipLibCheck: true,
          inlineSourceMap: false,
          declarationMap: false,
          noEmit: true,
          incremental: true,
          tsBuildInfoFile: paths.appTsBuildInfoFile,
        },
      },
      context: paths.appPath,
      diagnosticOptions: {
        syntactic: true,
      },
      mode: 'write-references',
      // profile: true,
    },
    issue: {
      // This one is specifically to match during CI tests,
      // as micromatch doesn't match
      // '../cra-template-typescript/template/src/App.tsx'
      // otherwise.
      include: [
        { file: '../**/src/**/*.{ts,tsx}' },
        { file: '**/src/**/*.{ts,tsx}' },
      ],
      exclude: [
        { file: '**/src/**/__tests__/**' },
        { file: '**/src/**/?(*.){spec|test}.*' },
        { file: '**/src/setupProxy.*' },
        { file: '**/src/setupTests.*' },
      ],
    },
    logger: {
      infrastructure: 'silent',
    },
  });

  // replace old with new ForkTsCheckerWebpackPlugin
  config.plugins.splice(forkTsCheckerWebpackPluginIndex, 1, newTsCheckerWebpackPlugin);

  return override(
     // i have project specific configs here using `customize-cra` (useBabelRC() for example)
  )(config);
}

I also disabled source map generations unfortunately. .env

GENERATE_SOURCEMAP=false

Hope that will help you people!

Any resolution to this yet?

Is there a way to pass that WITHOUT disabling sourcemaps in production ?!

TL;DR: Add this option to the script command --max_old_space_size=4096. Plenty of comments have buried a temporary fix shared by @buncismamen :

I also got the error with new project npx create-react-app and installing plotly

adding the memory flag to start scripts fixing the issue

"start": "react-scripts --max_old_space_size=4096 start",

Please, make sure you don’t allocate more RAM than your machine has.

Updating `@babel/core’ to the latest version didn’t help in my case.

the same problem, with a typescript setup

@Chnapy In my case is a JS context.

setting GENERATE_SOURCEMAP=false in .env work for me

My solution based on @AmrAbdulrahman solution:

module.exports = function override(config) {
    const forkTsCheckerWebpackPlugin = config.plugins.find(
        (plugin) => plugin.constructor.name === 'ForkTsCheckerWebpackPlugin',
    );
    if (forkTsCheckerWebpackPlugin) {
        forkTsCheckerWebpackPlugin.options.typescript.memoryLimit = 8192;
    }

    return config;
};

In my case, I tried increasing heap memory space to 4 GB but the build is getting very slow(Other solutions like Upgrading babel,CRA,Node didn’t work for me). When the build is success with 4GB Heapspace I observed that nearly 8 - 10 chunk files sizes are nearly 1MB. So I analyzed all those chunks using Source map explorer. In all chunks almost same libraries code is included (In my case those are Firebase, Video player, etc which are heavy)

So In my assumption when webpack is trying to bundle all these chunks It had to build all those libraries dependency graph in every chunk which in turn causes heap memory space issue. So I used Loadable components to lazy load those libraries.

After lazy loading all those libraries all chunks files size is reduced almost by half, And Build is getting success without increasing any heap space and build time also got reduced.

After optimization if I keep build in 6vCPU , i7 System it is taking around 3 - 4 minutes and I observed that based on the number of Cores available in the system build time is getting reduced. If I keep build in 2vCPU system it is taking around 20 - 25 mins like that sometimes

My personal experience with this bug: GENERATE_SOURCEMAP=false works in some cases, but not always:

  • enough RAM available => no bug
  • limited RAM (2GB - t2-small instance on AWS) => bug
    • BUT with additional --max_old_space_size=2048 => no bug (slow)
    • AND after successful build (for example as above) I can remove --max_old_space_size and the build will succeed (and run faster too). If, however, I then remove the cache from node_modules/.cache, the build fails again as before.

Maybe this can help debug the issue.

I reduced the amount of lazy loading to about a third of what it was before and the build time dropped to 1 minute. 😄

I am still getting this on Node 14.15.0 and it’s been almost a year now - any updates/solutions?

EDIT: resolved by upgrading to Node 15.0 nevermind, crashed on the following day even on Node 15

or me, removing import * as serviceWorker from "./serviceWorker";

fixed it. Guessing the import * was it.

Likewise this worked for me. I had this in my src/index.js file:

// ...
import * from './serviceWorker';
// ...
serviceWorker.unregister();

and I changed it to:

// ...
import { unregister } from './serviceWorker';
// ...
unregister();

and that seemed to do the trick, built in 58s (after taking significantly longer and ultimately failing).

I am getting this error every time I try to build. The following lines: react-scripts --max_old_space_size=4096 start or react-scripts --max-old-space-size=4096 start do nothing at all. Every crash report contains: “–max-old-space-size=2048”, line. So, on top of not working properly, create react app ignores command line arguments.

@luminaxster: You tl;dr is at least honest, because you did not read through the comments and linked issues. You fix is not a fix, not even a quick fix. It just delays the problem until you run out of memory again.

There are a lot of different solutions in this thread, because this error can have many different reasons.

If people have this problem, they should first look at their code maybe they do something stupid (like I did). Or they have circular references (https://github.com/facebook/create-react-app/issues/8413) Maybe node.js is being node.js and they need to remove and reinstall the modules. Bump the version of babel (https://github.com/facebook/create-react-app/issues/8096#issuecomment-567584040). Or their are using weird packages and need to fix/disable the generation of sourcemap (https://github.com/babel/babel/pull/10890).

If this doesn’t help: Create a new project, add your packages and import them. If the error occurs, maybe there is a problem with one of the dependencies. If there is no error: Start adding code until it stops working. Try to import max. one new dependency per iteration. If adding your code piece by piece is too much work, maybe rethink the overall architecture.

@BudickDa your issue is very specific and deals with workers and other stuff that a simple CRA user doesn’t experience. In our case we don’t have workers, and advanced type of implementation and we were having problems when you do npm run build.

Maybe you should ask your question in webpack library. 😉

@VehpuS IMO disabling type checking during build, even if it is hidden behind a flag, defeats the purpose of using Typescript. Also, since your workaround is editing node_modules manually, it will not be a good fit for people who (hopefully) have not checked in their node_modules and use proper CI builds.

This issue is likely caused by an underlying performance/compatibility problem and should therefor be directly addressed and fixed in an upcoming version.

3.3.1 includes babel 7.8.4 which should include the fix on babel’s side. Can anyone else confirm that 3.3.1 fixes the issue they were having previously?

It didn’t change anything on my side 😦

For me, removing import * as serviceWorker from "./serviceWorker";

fixed it. Guessing the import * was it.

Can confirm what @chawax was saying in our heap snapshot we see lots of retained size coming from source maps.

The problem in our codebase was traced to import * from './module'; statements. Make sure you avoid those in your test code and use import { whatYouNeed } from './module'; syntax instead to avoid adding lots of extra stuff in RAM that hangs around.

I had this issue running builds (only in Docker with fresh install of node_modules, not on macOS) after upgrading from Node v10 to v14 and running npm upgrade with "react-scripts": "^3.4.1" and "@babel/core": "^7.10.4".

Setting --max_old_space_size felt hacky to me so I avoided that option.

Adding GENERATE_SOURCEMAP=false to my .env file in the repo fixed the issue.

same problem here … fixing babel didn’t work

@ellis I retract my statement. During all these issues, appveyor had allocated a machine with lots of ram and super fast to help figure this out. This happened when I made the above change and did not realize it! What I was doing was creating an .eslintignore file and putting a * in it.

I found a workaround (that I would love to add as a pull request if none is planned) - skipping TS typechecking during the build stage for the project. This was useful as a way to unblock my project when it started exhibiting this behavior on build.

I managed to do this by manually editing node_modules/react-scripts/config/webpack.config.js to comment out the type checking section:

      // TypeScript type checking
      //   useTypeScript &&
      //     new ForkTsCheckerWebpackPlugin({
      //       typescript: resolve.sync('typescript', {
      //         basedir: paths.appNodeModules,
      //       }),
      //       async: isEnvDevelopment,
      //       useTypescriptIncrementalApi: true,
      //       checkSyntacticErrors: true,
      //       resolveModuleNameModule: process.versions.pnp
      //         ? `${__dirname}/pnpTs.js`
      //         : undefined,
      //       resolveTypeReferenceDirectiveModule: process.versions.pnp
      //         ? `${__dirname}/pnpTs.js`
      //         : undefined,
      //       tsconfig: paths.appTsConfig,
      //       reportFiles: [
      //         '**',
      //         '!**/__tests__/**',
      //         '!**/?(*.)(spec|test).*',
      //         '!**/src/setupProxy.*',
      //         '!**/src/setupTests.*',
      //       ],
      //       silent: true,
      //       // The formatter is invoked directly in WebpackDevServerUtils during development
      //       formatter: isEnvProduction ? typescriptFormatter : undefined,
      //     }),

I would like to have this option as a compilation flag, since it also reduces compilation time and can therefore be a useful tool in some scenarios.

tried some ways above, update react-scripts to 3.4.1, that didn’t work for me. but update @babel/core worked for me. I just run npm install @babel/core --save-dev script, by the way, the installed @babel/core version is 7.9.0.

@Chnapy I’m having the problem with typescript

@Chnapy we do use Typescript.

I still have the same out of memory issue with 3.3.1. Only 3.2.0 works.

Btw, I have two similar projects, more or less the same size and dependencies, one was failing with the out of memory with 3.3.0, one was working. With 3.3.1 both are now failing with the out of memory. 3.2.0 works for both.

Had to revert and pin my package.json to 3.2.0 to avoid heap memory issues as well

Thank you so much @petetnt, @yegor-sytnyk, and @buncismamen, I had the same error using build and adding max_old_space_size fixed it: "build": "react-scripts --max_old_space_size=4096 build" I know is just a hot-fix, but I take it meanwhile.

https://github.com/xiaoxiangmoe/create-react-app-running-out-of-memory

@ianschmitz

If we change “react-scripts”: “3.3.0” to “react-scripts”: “3.4.0”, the error will disappear.

Can anyone else confirm that 3.3.1 fixes the issue they were having previously?

It fixed it for me (I have pdfjs-dist among dependencies, that was causing the issue).

I still have the same out of memory issue with 3.3.1. Only 3.2.0 works.

Btw, I have two similar projects, more or less the same size and dependencies, one was failing with the out of memory with 3.3.0, one was working. With 3.3.1 both are now failing with the out of memory. 3.2.0 works for both.