On this page

    All together

    History

    To get the exact filename that will be loaded when require() is called, use the require.resolve() function.

    Putting together all of the above, here is the high-level algorithm in pseudocode of what require() does:

    require(X) from module at path Y
    1. If X is a core module,
       a. return the core module
       b. STOP
    2. If X begins with '/'
       a. set Y to the file system root
    3. If X is equal to '.', or X begins with './', '/' or '../'
       a. LOAD_AS_FILE(Y + X)
       b. LOAD_AS_DIRECTORY(Y + X)
       c. THROW "not found"
    4. If X begins with '#'
       a. LOAD_PACKAGE_IMPORTS(X, dirname(Y))
    5. LOAD_PACKAGE_SELF(X, dirname(Y))
    6. If a package map PACKAGE_MAP exists,
       a. Find the package ID for the package owning Y
            1. Let PARENT_PACKAGE_ID be FIND_PACKAGE_ID(dirname(Y), PACKAGE_MAP)
       b. LOAD_PACKAGE_MAP(X, PARENT_PACKAGE_ID, PACKAGE_MAP)
    7. LOAD_NODE_MODULES(X, dirname(Y))
    8. THROW "not found"
    
    MAYBE_DETECT_AND_LOAD(X)
    1. If X parses as a CommonJS module, load X as a CommonJS module. STOP.
    2. Else, if the source code of X can be parsed as ECMAScript module using
      DETECT_MODULE_SYNTAX defined in the ESM resolver,
      a. Load X as an ECMAScript module. STOP.
    3. THROW the SyntaxError from attempting to parse X as CommonJS in 1. STOP.
    
    LOAD_AS_FILE(X)
    1. If X is a file, load X as its file extension format. STOP
    2. If X.js is a file,
        a. Find the closest package scope SCOPE to X.
        b. If no scope was found
          1. MAYBE_DETECT_AND_LOAD(X.js)
        c. If the SCOPE/package.json contains "type" field,
          1. If the "type" field is "module", load X.js as an ECMAScript module. STOP.
          2. If the "type" field is "commonjs", load X.js as a CommonJS module. STOP.
        d. MAYBE_DETECT_AND_LOAD(X.js)
    3. If X.json is a file, load X.json to a JavaScript Object. STOP
    4. If X.node is a file, load X.node as binary addon. STOP
    
    LOAD_INDEX(X)
    1. If X/index.js is a file
        a. Find the closest package scope SCOPE to X.
        b. If no scope was found, load X/index.js as a CommonJS module. STOP.
        c. If the SCOPE/package.json contains "type" field,
          1. If the "type" field is "module", load X/index.js as an ECMAScript module. STOP.
          2. Else, load X/index.js as a CommonJS module. STOP.
    2. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP
    3. If X/index.node is a file, load X/index.node as binary addon. STOP
    
    LOAD_AS_DIRECTORY(X)
    1. If X/package.json is a file,
       a. Parse X/package.json, and look for "main" field.
       b. If "main" is a falsy value, GOTO 2.
       c. let M = X + (json main field)
       d. LOAD_AS_FILE(M)
       e. LOAD_INDEX(M)
       f. LOAD_INDEX(X) DEPRECATED
       g. THROW "not found"
    2. LOAD_INDEX(X)
    
    LOAD_NODE_MODULES(X, START)
    1. Try to interpret X as a combination of NAME and SUBPATH where the name
       may have a @scope/ prefix and the subpath begins with a slash (`/`).
    2. let DIRS = NODE_MODULES_PATHS(START)
    3. for each DIR in DIRS:
       a. LOAD_PACKAGE_EXPORTS(SUBPATH, DIR/NAME)
       b. LOAD_AS_FILE(DIR/X)
       c. LOAD_AS_DIRECTORY(DIR/X)
    
    NODE_MODULES_PATHS(START)
    1. let PARTS = path split(START)
    2. let I = count of PARTS - 1
    3. let DIRS = []
    4. while I >= 0,
       a. if PARTS[I] = "node_modules", GOTO d.
       b. DIR = path join(PARTS[0 .. I] + "node_modules")
       c. DIRS = DIRS + DIR
       d. let I = I - 1
    5. return DIRS + GLOBAL_FOLDERS
    
    FIND_PACKAGE_ID(PATH, PACKAGE_MAP)
    1. Find the PACKAGE_ID for the entry whose "path" is a parent directory of PATH
    2. If multiple entries are found, THROW "ambiguous resolution"
    3. If no entry was found, THROW "external file".
    4. return PACKAGE_ID
    
    LOAD_PACKAGE_MAP(X, PARENT_PACKAGE_ID, PACKAGE_MAP)
    1. Try to interpret X as a combination of NAME and SUBPATH where the name
       may have a @scope/ prefix and the subpath begins with a slash (`/`).
    2. Find the package map entry for key PARENT_PACKAGE_ID
    3. Look up NAME in the entry's "dependencies" map.
    4. If NAME is not found, THROW "not found".
    5. Let TARGET be PACKAGE_MAP.packages[dependencies[name]]
    6. Let PACKAGE_PATH be the resolved path of TARGET.
    7. LOAD_PACKAGE_EXPORTS(SUBPATH, PACKAGE_PATH)
    8. LOAD_AS_FILE(PACKAGE_PATH/SUBPATH)
    9. LOAD_AS_DIRECTORY(PACKAGE_PATH/SUBPATH)
    10. THROW "not found"
    
    LOAD_PACKAGE_IMPORTS(X, DIR)
    1. Find the closest package scope SCOPE to DIR.
    2. If no scope was found, return.
    3. If the SCOPE/package.json "imports" is null or undefined, return.
    4. If `--no-require-module` is not enabled
      a. let CONDITIONS = ["node", "require", "module-sync"]
      b. Else, let CONDITIONS = ["node", "require"]
    5. let MATCH = PACKAGE_IMPORTS_RESOLVE(X, pathToFileURL(SCOPE),
      CONDITIONS) defined in the ESM resolver.
    6. RESOLVE_ESM_MATCH(MATCH).
    
    LOAD_PACKAGE_EXPORTS(SUBPATH, PACKAGE_DIR)
    1. Parse PACKAGE_DIR/package.json, and look for "exports" field.
    2. If "exports" is null or undefined, return.
    3. If `--no-require-module` is not enabled
      a. let CONDITIONS = ["node", "require", "module-sync"]
      b. Else, let CONDITIONS = ["node", "require"]
    4. let MATCH = PACKAGE_EXPORTS_RESOLVE(pathToFileURL(PACKAGE_DIR), "." + SUBPATH,
       `package.json` "exports", CONDITIONS) defined in the ESM resolver.
    5. RESOLVE_ESM_MATCH(MATCH)
    
    LOAD_PACKAGE_SELF(X, DIR)
    1. Find the closest package scope SCOPE to DIR.
    2. If no scope was found, return.
    3. If the SCOPE/package.json "exports" is null or undefined, return.
    4. If the SCOPE/package.json "name" is not the first segment of X, return.
    5. let MATCH = PACKAGE_EXPORTS_RESOLVE(pathToFileURL(SCOPE),
       "." + X.slice("name".length), `package.json` "exports", ["node", "require"])
       defined in the ESM resolver.
    6. RESOLVE_ESM_MATCH(MATCH)
    
    RESOLVE_ESM_MATCH(MATCH)
    1. let RESOLVED_PATH = fileURLToPath(MATCH)
    2. If the file at RESOLVED_PATH exists, load RESOLVED_PATH as its extension
       format. STOP
    3. THROW "not found"

    The "ESM resolver" is defined in the ESM documentation.