Suggest an editImprove this articleRefine the answer for “module resolution”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**Module resolution** is the process by which Node.js finds the physical file (module) by the name specified in `require()` or `import`: in the core, in `node_modules`, or on a local path. **Key point:** Module resolution is the mechanism by which Node.js determines where the required module is physically located, going through built-in modules, local files, and `node_modules` until it finds the right file.Shown above the full answer for quick recall.Answer (EN)Image## 1. What is "module resolution" > **Module resolution** is the process by which Node.js **finds the physical file** (module) by the name specified in `require()` or `import`. Put simply: ```javascript const express = require('express'); ``` means: > Node.js has to find exactly where the **express** module is located: in the core, in `node_modules`, or on a local path. ## 2. The general search sequence When Node.js encounters `require('something')`, it goes through **five stages:** 1. Checks whether it is a **built-in (core)** module; 2. Checks whether it is a **path to a file** (`./`, `../`, `/`); 3. Otherwise treats it as a **module from** `node_modules`; 4. Looks for it in the nearest `node_modules`, walking up the directory tree; 5. If not found, throws a `MODULE_NOT_FOUND` error. ## 3. Types of modules Node.js can resolve | Type | Example | Description | |---|---|---| | **Core (built-in)** | `fs`, `path`, `os`, `http` | Built into Node.js, no installation required | | **Local files** | `./utils.js`, `../config.json` | Your own files | | **Packages (npm)** | `express`, `chalk`, `mongoose` | Looked up in `node_modules` | | **JSON / binary** | `config.json`, `addon.node` | Parsed automatically or loaded as binary | ## 4. The module resolution algorithm (for CommonJS) ### Example: ```javascript const utils = require('./utils'); ``` Node.js does the following: 1. Checks whether `'./utils'` is a path: - whether it starts with `./`, `../`, or `/`: yes. 2. Converts the path to an absolute one: ```javascript /Users/tim/project/utils ``` 3. Tries the following variants (in order): ```javascript utils.js utils.json utils.node utils/index.js utils/index.json utils/index.node ``` 4. If nothing is found -> an error: ```javascript Error: Cannot find module './utils' ``` ## 5. The algorithm for packages from `node_modules` Example: ```javascript const express = require('express'); ``` Node.js: 1. Looks for a built-in module `express` -> no. 2. Looks for `node_modules/express` in the current folder. 3. If not found -> moves up the tree: ```javascript /Users/tim/project/node_modules/express /Users/tim/node_modules/express /Users/node_modules/express /node_modules/express ``` 4. Found it -> reads the file `express/package.json`. 5. Looks for the `"main"` field in it: ```javascript { "name": "express", "main": "index.js" } ``` 6. Loads `/node_modules/express/index.js`. ## 6. A visual example ```javascript project/ │ ├── app.js ├── utils/ │ └── index.js └── node_modules/ └── lodash/ ├── package.json └── lodash.js ``` ```javascript require('./utils'); // → ./utils/index.js require('lodash'); // → ./node_modules/lodash/lodash.js require('fs'); // → a built-in Node.js module ``` ## 7. How Node.js chooses between `.js`, `.json`, and `.node` Node tries extensions **in this order**: 1. `.js` - a regular JavaScript file; 2. `.json` - automatically parsed into an object; 3. `.node` - a binary native module (C++). Example: ```javascript require('./config'); // will try config.js → config.json → config.node ``` ## 8. Module resolution for **ES Modules (ESM)** For ESM (`import/export`) the algorithm is different - **stricter**: - You must specify the **exact extension** (`.js`, `.mjs`, `.json`); - Folders with `index.js` are not searched for automatically; - `__dirname` and `__filename` are absent; - `"exports"` in `package.json` determines the available paths. Example: ```javascript import utils from './utils/index.js'; // the extension is mandatory ``` ## 9. How `package.json` affects module resolution Node.js looks at the fields: | Field | Purpose | |---|---| | `"main"` | The main entry point for CommonJS | | `"exports"` | A modern alternative for ESM / CJS | | `"type"` | Determines the module type (`commonjs` or `module`) | Example: ```javascript { "name": "my-lib", "main": "./dist/index.cjs", "exports": { "import": "./dist/index.mjs", "require": "./dist/index.cjs" }, "type": "module" } ``` Node will use `"exports"` instead of `"main"` if it is specified - this is the modern way to control which files can be imported from outside. ## 10. Caching during module resolution Once Node.js has resolved a module and loaded it, the result is stored in `require.cache`: ```javascript console.log(require.cache); ``` A repeated `require()` does not execute the file again, it simply returns its `exports` from the cache. This speeds up loading and prevents recursive cycles (`circular dependencies`). ## 11. Tools for debugging resolution If you want to see exactly **where** a module is picked up from: ```javascript node -p "require.resolve('express')" ``` Example output: ```javascript /Users/tim/project/node_modules/express/index.js ``` Or for a local file: ```javascript node -p "require.resolve('./utils')" ``` ## In one sentence: > **Module resolution** is the mechanism by which Node.js determines where a module specified in `require()` or `import` is physically located, going through built-in modules, local files, and `node_modules` until it finds the right file.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.