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.