Let’s break down the difference between import and require in JavaScript/Node.js:
1. Origin
require- Comes from CommonJS (CJS) module system.
- Default in Node.js (before ES modules).
- Example:
const fs = require('fs');
import- Comes from ES6 (ECMAScript Modules / ESM).
- Standardized in modern JavaScript.
- Example:
import fs from 'fs';
2. Synchronous vs Asynchronous
require- Loads modules synchronously (blocking).
- Best for server-side (Node.js), not browsers.
import- Loads asynchronously (non-blocking).
- Works in both browsers and Node.js (with
"type": "module").
3. Static vs Dynamic
require- Is dynamic → you can call it anywhere in the code.
- Example:
if (condition) { const moduleA = require('./moduleA'); }
import- Is static → must be declared at the top level of the file.
- Example:
import moduleA from './moduleA'; // must be at top
4. Exports Handling
require- Works with
module.exportsandexports. - Example:
// module.js module.exports = { name: "Himanshu" }; // main.js const data = require('./module'); console.log(data.name);
- Works with
import- Works with default export and named exports.
- Example:
// module.js export const name = "Himanshu"; export default function greet() { console.log("Hello"); } // main.js import greet, { name } from './module.js';
5. Tree Shaking (Optimization)
require- No tree shaking support (unused code isn’t removed).
import- Supports tree shaking in bundlers like Webpack, Rollup (better for frontend performance).
✅ Quick Summary
| Feature | require (CommonJS) | import (ESM) |
|---|---|---|
| Module System | CommonJS | ES Modules |
| Execution | Synchronous | Asynchronous |
| Placement | Anywhere (dynamic) | Top-level only |
| Exports Used | module.exports | export / export default |
| Tree Shaking | ❌ Not supported | ✅ Supported |
| Environment | Node.js | Node.js + Browsers |
👉 If you’re writing modern JavaScript (frontend or Node.js with "type": "module" in package.json), prefer import.
👉 If you’re working in older Node.js projects, you’ll mostly see require.
