Skip to main content

How to Resolve the "Module not found: Can't resolve" Error for Node.js Core Modules in JavaScript

When working with modern JavaScript bundlers like Webpack 5+, you may encounter the Module not found: Error: Can't resolve '...' error for modules like assert, util, crypto, http, stream, or other Node.js core modules.

This error occurs because Webpack 5 and newer versions no longer automatically include polyfills for native Node.js modules. This is a deliberate change to encourage front-end code to be independent of Node.js-specific APIs, which do not exist in the browser.

This guide will explain the two main solutions to this problem: either providing a browser-compatible polyfill for the module or, more commonly, telling Webpack to ignore it.

The Core Problem: Webpack 5+ No Longer Polyfills Node.js Modules​

In the past, bundlers like Webpack would often automatically bundle a browser-friendly version (a "polyfill") of a Node.js module if it was referenced in your code. This was convenient but could lead to large, unnecessary libraries being included in your front-end bundle.

Webpack 5 stopped this behavior. Now, if a package you are using was originally written for Node.js and contains a line like const assert = require('assert');, Webpack will fail with an error because it doesn't know how to resolve assert in a browser environment.

Example of the error:

Module not found: Error: Can't resolve 'assert' in ...

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

This error message is very informative. It tells you exactly what has changed and gives you two options: polyfill it or exclude it.

Solution 1 (Most Common): Telling Webpack to Ignore the Module​

In over 99% of cases, you do not actually need the Node.js module in your client-side code. It's often included as an optional dependency or for a server-side-only feature of a library. The easiest and most common solution is to tell Webpack that it can ignore this module or substitute it with an empty one.

For create-react-app (and similar tools)​

Many build toolchains look for a browser field in your package.json file to handle browser-specific configurations.

The solution is to add a browser field to your package.json and set the module to false.

// package.json
{
"name": "my-app",
"version": "1.0.0",
"dependencies": { ... },

// Add this section
"browser": {
"assert": false,
"util": false,
"stream": false,
"crypto": false,
"http": false,
"https": false,
"os": false,
"url": false
}
}
note

Add an entry for each module that is causing a "Can't resolve" error. Setting it to false tells the bundler to substitute it with an empty module. After making this change, you must restart your development server.

For Custom Webpack Configurations​

If you have direct access to your webpack.config.js file, you can achieve the same result using the resolve.fallback property.

Solution:

// webpack.config.js
module.exports = {
// ... other config
resolve: {
fallback: {
"assert": false,
"util": false,
// ... add an entry for each module that fails
}
}
};

Solution 2 (Advanced): Installing and Using a Polyfill​

In the rare case that your application actually needs the functionality of the Node.js module in the browser, you must provide a polyfill. A polyfill is a browser-compatible version of the native Node.js module.

Solution:

  1. Install the polyfill package. Many polyfills are available on npm. For example, for the stream module, you would use stream-browserify.
    npm install stream-browserify
  2. Configure Webpack to use it. In your webpack.config.js, update the resolve.fallback property to point the Node.js module name to the polyfill you installed.
    // webpack.config.js
    module.exports = {
    // ... other config
    resolve: {
    fallback: {
    "stream": require.resolve("stream-browserify")
    }
    }
    };

This is a more complex solution and should only be used if you are sure you need the module's functionality on the client side.

A Special Case: Next.js​

In a Next.js application, Node.js modules can only be used in server-side code (like getServerSideProps or getStaticProps). If you try to import one in a component that renders on the client, you will get the "Can't resolve" error.

  • If you need the module's functionality: Make sure your code is running only on the server.
  • If you do not need the module: You can configure Next.js to ignore it on the client side by modifying your next.config.js file.

Solution (next.config.js)

// next.config.js for Webpack 5+
module.exports = {
webpack: (config) => {
// This is the standard way to disable client-side polyfills in Next.js.
config.resolve.fallback = {
fs: false,
assert: false,
// ... add other modules here
};

return config;
},
};

Conclusion​

The Module not found: Can't resolve ... error for Node.js core modules is a direct result of Webpack 5+ no longer providing automatic browser polyfills.

  • The most common and recommended solution is to tell your bundler to ignore the module, as it's usually not needed for client-side code. This is typically done by adding a browser field to your package.json or by configuring resolve.fallback in your webpack.config.js.
  • If you genuinely need the module's functionality in the browser, you must install a suitable polyfill package and configure Webpack to use it.
  • In frameworks like Next.js, this error is a signal that you are trying to use server-side code in a client-side component.