Skip to content

Fixing "Module not found: Can't resolve 'fs'" in Next.js

The "Module not found: Can't resolve 'fs'" error is a common issue that occurs when Node.js-specific modules like fs (file system) are incorrectly used in browser/client-side code in Next.js applications.

Understanding the Problem

Next.js uses a hybrid rendering approach that allows both server-side and client-side execution. Node.js modules like fs, path, and crypto are only available in server-side environments and cannot run in browsers.

WARNING

Attempting to use Node.js modules directly in client components will always fail, as browsers don't have access to the Node.js runtime environment.

Root Causes

This error typically occurs when:

  1. Server-side code is mistakenly used in client components
  2. Mixed server/client modules are imported in client code
  3. Third-party libraries depend on Node.js modules
  4. Incorrect Webpack configuration

Best Solution: Proper Code Separation

The most maintainable approach is to properly separate server and client code according to Next.js conventions.

Use Data Fetching Methods

Only use Node.js modules within Next.js data fetching methods:

js
// pages/my-page.js (or app directory equivalent)
export async function getServerSideProps() {
  const fs = require('fs');
  const fileContent = fs.readFileSync('/path/to/file', 'utf8');
  
  return {
    props: {
      content: fileContent
    }
  };
}

export default function MyPage({ content }) {
  // Client-side component
  return <div>{content}</div>;
}

Server Components (Next.js 13+)

With the App Router, use Server Components for server-side operations:

js
// app/my-page/page.js
import { promises as fs } from 'fs';

export default async function MyPage() {
  // This runs on the server only
  const file = await fs.readFile(process.cwd() + '/data/file.txt', 'utf8');
  
  return (
    <div>
      <h1>File Content</h1>
      <pre>{file}</pre>
    </div>
  );
}

Isolate Server-Only Code

Create separate modules for server-only code:

js
// lib/server-utils.js (server-only)
import { promises as fs } from 'fs';

export async function readDataFile() {
  return fs.readFile('./data.json', 'utf8');
}

// lib/client-utils.js (client-safe)
export function formatData(data) {
  return JSON.parse(data);
}

Use server-only Package

For better code organization, mark server-only files explicitly:

bash
npm install server-only
js
// lib/server-data.js
import "server-only";
import { promises as fs } from 'fs';

export async function getServerData() {
  const data = await fs.readFile('./data.json', 'utf8');
  return JSON.parse(data);
}

Webpack Configuration Solutions

If you must use Node.js modules in specific edge cases, modify your next.config.js:

Webpack 5 Configuration

js
// next.config.js
module.exports = {
  webpack: (config, { isServer }) => {
    if (!isServer) {
      config.resolve.fallback = {
        fs: false,
        path: false,
        os: false,
        // Add other Node.js modules as needed
      };
    }
    return config;
  },
};

Handling Specific Node.js Modules

js
// next.config.js
module.exports = {
  webpack: (config, { nextRuntime }) => {
    if (nextRuntime !== "nodejs") {
      const { IgnorePlugin } = require("webpack");
      const ignoreNode = new IgnorePlugin({ resourceRegExp: /node:.*/ });
      config.plugins.push(ignoreNode);
    }
    return config;
  },
};

Common Scenarios and Fixes

Third-Party Libraries

Some libraries may have Node.js dependencies. For example, if using bcrypt, switch to bcryptjs:

bash
npm uninstall bcrypt
npm install bcryptjs
js
import bcrypt from "bcryptjs"; // Instead of 'bcrypt'

Lingui Library Issue

If using Lingui macros, configure SWC plugin:

js
// next.config.js
module.exports = {
  experimental: {
    swcPlugins: [["@lingui/swc-plugin", {}]],
  },
};

Edge Runtime Configuration

Ensure you're not accidentally using Edge Runtime with Node.js modules:

js
// Remove this if you need Node.js modules
export const runtime = 'edge'; // Change to 'nodejs' or remove

Debugging Tips

  1. Check for unused imports - Remove any unused Node.js module imports
  2. Verify module usage - Ensure Node.js modules are only used in server contexts
  3. Review third-party dependencies - Check if any dependencies require Node.js modules
  4. Inspect bundle - Use npm run build to see where the error occurs

DANGER

Avoid the browser field hack in package.json as it only suppresses errors without fixing the underlying issue:

json
{
  "browser": {
    "fs": false,
    "path": false
  }
}

Conclusion

The "Module not found: Can't resolve 'fs'" error is fundamentally a code organization issue. The best solution is to:

  1. Separate server and client code appropriately
  2. Use Next.js data fetching methods for server-side operations
  3. Leverage Server Components in Next.js 13+
  4. Mark server-only files with the server-only package
  5. Only use Webpack configuration as a last resort

By following these patterns, you'll create more maintainable Next.js applications that properly leverage both server and client capabilities.