search
Javascript star Featured

How to Fix: Uncaught ReferenceError: require is not defined Error in Javascript

Learn how to fix the 'Uncaught ReferenceError: require is not defined' error in JavaScript. This comprehensive guide covers CommonJS, ES6 modules, and browser compatibility.

person By Gautam Sharma
calendar_today January 2, 2026
schedule 12 min read
JavaScript require CommonJS ES6 Modules Error Frontend Development Node.js

The ‘Uncaught ReferenceError: require is not defined’ error is a common JavaScript issue that occurs when trying to use Node.js-style require() in environments that don’t support it, such as browsers. This error typically happens when CommonJS modules are used in browser environments or when module bundlers aren’t properly configured.

This comprehensive guide explains what causes this error, why it happens, and provides multiple solutions to fix it in your JavaScript projects with clean code examples and directory structure.


What is the require is not defined Error?

The “Uncaught ReferenceError: require is not defined” error occurs when:

  • Using require() in browser environments
  • CommonJS modules aren’t properly transpiled for browsers
  • Module bundler configuration issues
  • Node.js code running in browser context
  • Improper module system mixing

Common Error Messages:

  • Uncaught ReferenceError: require is not defined
  • ReferenceError: require is not defined
  • require is not defined in ES module scope
  • Cannot use import statement outside a module
  • Module not found: Error: Can't resolve 'module-name'

Understanding the Problem

The require() function is part of CommonJS, which is Node.js’s module system. Browsers don’t natively support CommonJS, so require() is not available in browser environments. This creates a fundamental incompatibility when trying to use Node.js-style modules in web applications.

Typical JavaScript Project Structure:

my-js-app/
├── package.json
├── webpack.config.js
├── vite.config.js
├── src/
│   ├── main.js
│   ├── utils/
│   │   ├── helpers.js
│   │   └── validators.js
│   ├── components/
│   │   └── app.js
│   ├── node_modules/
│   └── styles/
├── public/
│   └── index.html
└── dist/

Solution 1: Use ES6 Import/Export Instead of require

The most common solution is to use ES6 modules instead of CommonJS.

❌ Using require in Browser:

// ❌ This will cause "require is not defined" in browsers
const express = require('express'); // ❌ Node.js only
const fs = require('fs'); // ❌ Node.js only
const myModule = require('./myModule'); // ❌ Causes error in browser

✅ Using ES6 Import/Export:

myModule.js:

// ✅ ES6 module export
export const myFunction = () => {
  return 'Hello from ES6 module';
};

export const myVariable = 'ES6 module variable';

// ✅ Default export
export default {
  name: 'My ES6 Module',
  version: '1.0.0'
};

main.js:

// ✅ ES6 import instead of require
import myModule, { myFunction, myVariable } from './myModule.js';
import { someHelper } from './utils/helpers.js';

// ✅ Use the imported modules
console.log(myFunction());
console.log(myVariable);
console.log(myModule.name);

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>ES6 Modules Example</title>
</head>
<body>
  <div id="app"></div>
  <!-- ✅ Use type="module" for ES6 imports -->
  <script type="module" src="./src/main.js"></script>
</body>
</html>

Solution 2: Configure Module Bundler for Browser

Use a module bundler like Webpack, Vite, or Rollup to handle CommonJS modules.

❌ Without Bundler Configuration:

// ❌ Direct browser usage of CommonJS
// This won't work in browsers
const _ = require('lodash'); // ❌ Error in browser

✅ With Webpack Configuration:

webpack.config.js:

const path = require('path');

module.exports = {
  entry: './src/main.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }
    ]
  },
  resolve: {
    fallback: {
      // ✅ Handle Node.js built-in modules for browser
      "fs": false,
      "path": require.resolve("path-browserify"),
      "crypto": require.resolve("crypto-browserify")
    }
  },
  mode: 'development'
};

package.json:

{
  "name": "my-js-app",
  "version": "1.0.0",
  "scripts": {
    "build": "webpack",
    "dev": "webpack serve --mode development"
  },
  "dependencies": {
    "lodash": "^4.17.21"
  },
  "devDependencies": {
    "webpack": "^5.0.0",
    "webpack-cli": "^4.0.0",
    "webpack-dev-server": "^4.0.0",
    "babel-loader": "^8.0.0",
    "@babel/core": "^7.0.0",
    "@babel/preset-env": "^7.0.0",
    "path-browserify": "^1.0.1",
    "crypto-browserify": "^3.12.0"
  }
}

Solution 3: Use Vite for Modern Development

Vite provides excellent support for both ES6 modules and CommonJS.

❌ Without Vite Configuration:

// ❌ Direct usage without proper bundling
const express = require('express'); // ❌ Won't work

✅ With Vite Configuration:

vite.config.js:

import { defineConfig } from 'vite';
import { resolve } from 'path';

export default defineConfig({
  build: {
    rollupOptions: {
      input: {
        main: resolve(__dirname, 'index.html'),
        // ✅ Multiple entry points if needed
      }
    }
  },
  define: {
    // ✅ Define global variables for browser compatibility
    global: 'globalThis',
  },
  resolve: {
    alias: {
      // ✅ Alias for compatibility
      '@': resolve(__dirname, 'src'),
    }
  }
});

main.js (Vite):

// ✅ Vite supports both ES6 imports and CommonJS through plugins
import { createApp } from 'vue'; // ✅ ES6 import
import _ from 'lodash'; // ✅ Works with Vite's CommonJS support

// ✅ Use the imported modules
const app = createApp({
  data() {
    return {
      message: 'Hello Vite!'
    }
  }
});

app.mount('#app');

Solution 4: Use Browserify for CommonJS in Browser

Browserify can bundle CommonJS modules for browser use.

❌ Without Browserify:

// ❌ Direct browser usage
const myModule = require('./myModule'); // ❌ Error

✅ With Browserify:

package.json:

{
  "scripts": {
    "build": "browserify src/main.js -o dist/bundle.js",
    "dev": "watchify src/main.js -o dist/bundle.js -v"
  },
  "devDependencies": {
    "browserify": "^17.0.0",
    "watchify": "^4.0.0"
  }
}

main.js:

// ✅ This will work with Browserify
const myModule = require('./myModule');
const _ = require('lodash');

console.log(myModule.myFunction());

Solution 5: Use CDN for Third-Party Libraries

For simple projects, use CDN versions of libraries instead of require.

❌ Using require for CDN libraries:

// ❌ This won't work in browser
const moment = require('moment'); // ❌ Error

✅ Using CDN:

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CDN Example</title>
  <!-- ✅ Load library from CDN -->
  <script src="https://cdn.jsdelivr.net/npm/moment@2.29.4/moment.min.js"></script>
</head>
<body>
  <div id="app"></div>
  <script>
    // ✅ Library is now available globally
    console.log(moment().format('YYYY-MM-DD'));
  </script>
</body>
</html>

Solution 6: Conditional Module Loading

Create conditional loading based on environment.

utils/moduleLoader.js:

// ✅ Universal module loader that works in both Node.js and browser
let moduleLoader;

if (typeof window !== 'undefined' && typeof window.require === 'undefined') {
  // ✅ Browser environment
  moduleLoader = {
    load: (moduleName) => {
      // ✅ Handle browser-specific module loading
      if (moduleName === 'lodash') {
        return window._; // ✅ Assume loaded via CDN
      }
      throw new Error(`Module ${moduleName} not available in browser`);
    }
  };
} else if (typeof require !== 'undefined') {
  // ✅ Node.js environment
  moduleLoader = {
    load: (moduleName) => {
      return require(moduleName);
    }
  };
} else {
  // ✅ Neither environment supports modules
  moduleLoader = {
    load: () => {
      throw new Error('No module system available');
    }
  };
}

export default moduleLoader;

Solution 7: Use Dynamic Imports for Modern Browsers

Use dynamic imports for runtime module loading.

main.js:

// ✅ Dynamic import for modern browsers
async function loadModule() {
  try {
    // ✅ Dynamic import works in modern browsers
    const { default: myModule } = await import('./myModule.js');
    return myModule;
  } catch (error) {
    console.error('Failed to load module:', error);
    return null;
  }
}

// ✅ Usage
loadModule().then(module => {
  if (module) {
    console.log(module.myFunction());
  }
});

// ✅ Conditional loading based on feature detection
if ('import' in window) {
  // ✅ Modern browser with dynamic import support
  loadModule();
} else {
  // ✅ Fallback for older browsers
  console.log('Dynamic imports not supported');
}

Working Code Examples

Complete Browser-Compatible Module System:

// src/utils/UniversalModule.js
class UniversalModule {
  static isNode() {
    return typeof process !== 'undefined' && 
           process.versions && 
           process.versions.node;
  }

  static isBrowser() {
    return typeof window !== 'undefined' && 
           typeof window.document !== 'undefined';
  }

  static async load(moduleName) {
    if (this.isNode()) {
      // ✅ Node.js environment
      return this.loadNodeModule(moduleName);
    } else if (this.isBrowser()) {
      // ✅ Browser environment
      return this.loadBrowserModule(moduleName);
    } else {
      throw new Error('Unknown environment');
    }
  }

  static loadNodeModule(moduleName) {
    try {
      // ✅ Use require in Node.js
      return require(moduleName);
    } catch (error) {
      console.error(`Failed to load Node module ${moduleName}:`, error);
      return null;
    }
  }

  static async loadBrowserModule(moduleName) {
    try {
      // ✅ Use dynamic import in browser
      switch (moduleName) {
        case 'lodash':
          // ✅ Assume loaded via CDN or bundled
          return window._ || await import('https://cdn.skypack.dev/lodash');
        case 'moment':
          return window.moment || await import('https://cdn.skypack.dev/moment');
        default:
          // ✅ Try to import as ES module
          return await import(`./${moduleName}.js`);
      }
    } catch (error) {
      console.error(`Failed to load browser module ${moduleName}:`, error);
      return null;
    }
  }
}

// ✅ Usage example
async function initApp() {
  const lodash = await UniversalModule.load('lodash');
  const moment = await UniversalModule.load('moment');

  if (lodash) {
    console.log('Lodash loaded:', typeof lodash);
  }

  if (moment) {
    console.log('Current date:', moment().format('YYYY-MM-DD'));
  }
}

initApp();

Module Bundler Configuration:

// webpack.config.js - Production-ready configuration
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/main.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.[contenthash].js',
    clean: true
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: [
              ['@babel/preset-env', {
                targets: {
                  browsers: ['> 1%', 'last 2 versions']
                }
              }]
            ]
          }
        }
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './public/index.html'
    })
  ],
  resolve: {
    fallback: {
      "fs": false,
      "path": require.resolve("path-browserify"),
      "crypto": require.resolve("crypto-browserify"),
      "stream": require.resolve("stream-browserify"),
      "buffer": require.resolve("buffer")
    }
  },
  optimization: {
    splitChunks: {
      chunks: 'all'
    }
  },
  mode: 'production'
};

Best Practices for Module Management

1. Use ES6 Modules by Default

// ✅ Prefer ES6 modules for new projects
import { myFunction } from './myModule.js';

2. Configure Module Bundlers Properly

// ✅ Proper bundler configuration handles CommonJS
// Webpack, Vite, or Rollup configuration

3. Use Dynamic Imports for Code Splitting

// ✅ Use dynamic imports for lazy loading
const loadFeature = async () => {
  const { feature } = await import('./feature.js');
  return feature;
};

4. Handle Environment Differences

// ✅ Check environment before using environment-specific features
if (typeof window !== 'undefined') {
  // Browser code
} else {
  // Node.js code
}

Debugging Steps

Step 1: Identify the Problem

# Check if require is being used in browser code
grep -r "require(" src/

Step 2: Check Browser Console

# Open browser dev tools
# Check Console tab for "require is not defined" errors
# Check Network tab for failed module loads

Step 3: Verify Module System

// Add debugging to identify environment
console.log('Environment:', typeof window !== 'undefined' ? 'Browser' : 'Node.js');
console.log('Require available:', typeof require !== 'undefined');

Step 4: Test Module Loading

// Test different module loading approaches
try {
  // Test ES6 import
  import('./testModule.js');
  console.log('ES6 modules supported');
} catch (error) {
  console.log('ES6 modules not supported:', error);
}

Common Mistakes to Avoid

1. Using require in Browser Code

// ❌ Don't use require in browser
const fs = require('fs'); // ❌ Node.js only

2. Mixing Module Systems

// ❌ Don't mix require and import in same file
const module1 = require('./module1'); // ❌ CommonJS
import module2 from './module2'; // ✅ ES6 (but mixing is problematic)

3. Forgetting Module Type in HTML

<!-- ❌ Missing type="module" -->
<script src="main.js"></script>

<!-- ✅ Correct -->
<script type="module" src="main.js"></script>

4. Not Configuring Bundlers for Browser

// ❌ Using Node.js modules without browser fallbacks
const fs = require('fs'); // ❌ Won't work in browser

Performance Considerations

1. Use Tree Shaking

// ✅ Import only what you need
import { debounce } from 'lodash'; // ✅ Tree-shakable
// Instead of: import _ from 'lodash';

2. Optimize Bundle Size

# ✅ Analyze bundle size
npm install -g webpack-bundle-analyzer
# Use in your bundler configuration

3. Implement Code Splitting

// ✅ Use dynamic imports for code splitting
const loadDashboard = async () => {
  const { Dashboard } = await import('./Dashboard.js');
  return Dashboard;
};

Security Considerations

1. Validate Module Sources

// ✅ Only import from trusted sources
// Avoid dynamic imports from user input
const userInput = 'user-provided-string';
// ❌ Don't do: import(userInput);

2. Sanitize Dynamic Module Paths

// ✅ Validate dynamic module paths
function isValidModulePath(path) {
  return /^[a-zA-Z0-9/_-]+$/.test(path);
}

Testing Module Systems

1. Unit Test Module Loading

// Using Jest or similar testing framework
describe('Module loading', () => {
  test('should handle browser environment', () => {
    // Mock browser environment
    global.window = { document: {} };
    global.require = undefined;
    
    // Test your module loading logic
    expect(typeof window).toBe('object');
  });
  
  test('should handle Node.js environment', () => {
    // Test with Node.js environment
    expect(typeof process).toBe('object');
    expect(typeof require).toBe('function');
  });
});

2. Test Dynamic Imports

test('should load modules dynamically', async () => {
  const module = await import('./testModule.js');
  expect(module).toBeDefined();
});

Alternative Solutions

1. Use SystemJS for Dynamic Loading

// ✅ SystemJS provides dynamic module loading
System.import('myModule').then(module => {
  // Use module
});

2. Use AMD (RequireJS) for Legacy Support

// ✅ AMD modules for legacy browser support
define(['lodash', 'moment'], function(_, moment) {
  // Module code
});

Migration Checklist

  • Replace all require() calls with ES6 imports
  • Configure module bundler for browser compatibility
  • Test in browser environment
  • Verify all dependencies work in browser
  • Update build scripts
  • Run comprehensive tests
  • Update documentation for team members

Conclusion

The ‘Uncaught ReferenceError: require is not defined’ error is a common JavaScript issue that occurs when trying to use Node.js-style modules in browser environments. By following the solutions provided in this guide—whether through ES6 modules, proper bundler configuration, or conditional loading—you can ensure your JavaScript applications work correctly in both Node.js and browser environments.

The key is to understand that require() is a Node.js feature and browsers use different module systems. With proper module management, bundler configuration, and environment-aware code, your JavaScript applications will be compatible across different environments and provide a seamless development experience.

Remember to use ES6 modules by default, configure your build tools properly, and test thoroughly across different environments to ensure your applications are robust and maintainable.

Gautam Sharma

About Gautam Sharma

Full-stack developer and tech blogger sharing coding tutorials and best practices

Related Articles

Javascript

[SOLVED] Cannot use import statement outside a module Error in JavaScript

Learn how to fix the 'Cannot use import statement outside a module' error in JavaScript applications. This comprehensive guide covers ES6 modules, Node.js, and browser compatibility.

January 2, 2026
Javascript

Fix: addEventListener is not a function error in JavaScript

Learn how to fix the 'addEventListener is not a function' error in JavaScript applications. This comprehensive guide covers DOM manipulation, Node.js, and browser compatibility.

January 2, 2026
Javascript

Fix: CORS policy: No 'Access-Control-Allow-Origin' Error in Node & Javascript

Learn how to fix the 'CORS policy: No Access-Control-Allow-Origin' error in JavaScript and Node.js applications. This comprehensive guide covers CORS configuration, headers, and best practices.

January 2, 2026