Skip to content

Fall back to a user-configured directory when resolving imports #67354

Open

Description

@cos4ni2s

What is the problem this feature will solve?

Node.js doesn't support a user-configured fallback directory when trying to resolve imports. It only resolves those imports against a node_modules directory in the same (or ancestor) directory as the importing file. This current architecture falls short for standalone scripts, which don't have a node_modules directory around.

This artificial limitation hinders Node.js's ability to fulfill its goal to "Run JavaScript Everywhere".

What is the feature you are proposing to solve the problem?

Fall back to a user-configured directory when normal resolution fails

What alternatives have you considered?

  • Hardcoding absolute paths using the file:// protocol
    • fragile
    • not portable
  • A symlinked node_modules in the importing file's directory
    • overridden once npm install is executed
  • A symlinked node_modules in a shared ancestor directory
    • must be located at the filesystem root to cover every location
  • A register hook that retries from a specified directory after an ERR_MODULE_NOT_FOUND/MODULE_NOT_FOUND error
    • must be included in every importing file
    • doesn't work with static imports
    • isn't compatible with tooling (e.g., IDEs don't run it, so they treat the imported modules like unresolved ones)

Activity

  1. ljharb commented on Nov 9, 2026

    @ljharb
    SponsorMember

    This is a very intentional design choice. CJS has a deprecated env var for this, and it's proven to be a horrifically terrible idea to make the location of modules configurable, which is why ESM explicitly avoids doing so.

    Standalone scripts can use SEA to package up a bundled file into a single executable; that's the path I'd suggest.

  2. cos4ni2s commented on Nov 10, 2026

    @cos4ni2s
    Author

    This is a very intentional design choice.

    And also a limitation that causes dependency duplication (reinstalling the same dependencies for each project) and friction (setting up a project and populating a node_modules directory for the simplest tasks).

    it's proven to be a horrifically terrible idea

    Runtimes for many mainstream languages (Python, Ruby, Java, PHP, C#, ...) support user-configurable locations. What's so horrible about it?

    Standalone scripts can use SEA to package up a bundled file into a single executable

    A single executable application:

    • requires bundling dependency code alongside application code into a standalone JavaScript file,
    • requires generating a blob that contains all the necessary information to run the bundled script,
    • requires injection of the generated blob into a copy of the Node.js binary,
    • requires separate builds for each target operating system and CPU architecture,
    • throws an error when attempting to use import() to load modules from the filesystem,
    • produces binaries, and large ones,
    • ...
    • and requires rebuilding whenever something changes.

    A simple script file requires none of this

  3. ljharb commented on Nov 10, 2026

    @ljharb
    SponsorMember

    Yep, that's true. but once you add dependencies, you need a way to package them. A single folder containing a script with node_modules and package.json is a lot easier to manage, and a lot more portable, than an arbitrary location.

    It is a limitation - but a beneficial one. Dependency duplication is a feature, not a bug, and it's why npm/cargo/nix are the only non-broken package ecosystems in existence. As for friction, that's unavoidable if you have dependencies - if you want no friction, then you'd need to avoid having any dependencies.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature requestIssues requesting new Node.js features.

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions