Fix the 'module not found' error in Next.js
By Flavio Copes
Fix the Next.js Module not found: Can't resolve 'net' error, caused by running backend code on the client; move that library call into getStaticProps instead.
If Next.js gives you a “module not found” error mentioning a Node.js core module like net, fs or tls, the fix is not to install anything. The fix is to move the code that needs that module to the server side, into getStaticProps() or getServerSideProps().
While doing some sanitization on a variable in Next.js I ran into this weird problem:
Module not found: Error: Can't resolve 'net'
You might have some variation of it, which says a core Node.js module is missing. fs and child_process are common ones too.
Why this happens
Next.js compiles your page code twice: once for the server, and once for the browser.
The browser bundle has no access to Node.js core modules. There is no net, no fs, no tls in a browser. So when a library you use in a component tries to load one of them, the bundler can’t resolve it, and the build fails with this error.
In other words: Next.js is trying to run backend code in the frontend.
The wrong fix
Do NOT npm install net or anything like that. There happens to be an old, unrelated package on npm with that name, so the install succeeds, but it won’t fix anything. If you already tried, run npm uninstall on those modules.
The real fix
Find the library that needs the Node environment, and make sure it only runs on the server.
In my case it was the DOMPurify library. I was using it inside the component, but instead I had to use it in the getStaticProps() method.
That method runs at build time in the Node environment, where that library expected to be ran into.
The nice part is that Next.js strips getStaticProps() (and getServerSideProps()) from the client bundle, along with the imports only used inside it. The library never reaches the browser, so the error goes away.
The component then receives the already-processed data through props:
export async function getStaticProps() {
const description = sanitize(rawDescription) //runs in Node, at build time
return { props: { description } }
}
If the work needs to happen per request instead of at build time, use getServerSideProps(). Same idea: the code runs in Node, the browser only gets the result.
One way to spot the culprit: the error output usually shows the import trace, the chain of files leading to the module it can’t resolve. Follow that chain and you’ll find which of your imports pulled in the server-only code.
Related posts about next: