Skip to content

Tracking Issue: Syncify the ESM Loader #55782

Description

@GeoffreyBooth

The code under lib/internal/modules/esm, a.k.a. the ESM loader, contains many functions that are async. We should refactor as many of these as possible, ideally all of them, to be synchronous. This should improve the performance of evaluating ESM code, bringing it roughly on par with the speed of running CommonJS code.

Longer term, once the ESM loader is synchronous and we land the synchronous module customization hooks, we could deprecate monkey-patching the CommonJS loader and merge together the CommonJS and ESM loaders, eliminating duplication: #50356.

This issue will track our progress syncifying the various files and functions of the ESM loader until we can get as much of it to be as synchronous as possible.

The files to be updated, all underlib/internal/modules:

  • run_main.js: asyncRunEntryPointWithESMLoader
  • esm/fetch_module.js: fetchWithRedirects
  • esm/fetch_module.js: isLocalAddress
  • esm/hooks.js: Hooks class (the async methods here probably don’t need updating as they will be removed once we migrate to the synchronous customization hooks)
  • esm/hooks.js: nextHookFactory
  • esm/load.js: getSource esm: syncify default path of ModuleLoader.load #57419
  • esm/load.js: defaultLoad esm: syncify default path of ModuleLoader.load #57419
  • esm/loader.js: ModuleLoader.eval
  • esm/loader.js: ModuleLoader.getModuleJobForImport
  • esm/loader.js: ModuleLoader.loadAndTranslate
  • esm/loader.js: ModuleLoader.import
  • esm/loader.js: ModuleLoader.load
  • esm/module_job.js: ModuleJob._link
  • esm/module_job.js: ModuleJob._instantiate
  • esm/module_job.js: ModuleJob.run
  • esm/module_job.js: ModuleJobSync.run
  • esm/translators.js: wasm handler, via translators.set('wasm', ...
  • esm/utils.js: importModuleDynamicallyCallback
  • esm/utils.js: initializeHooks (might not need updating as we will remove this once the synchronous customization hooks land
  • esm/worker.js: customizedModuleWorker (might not need updating as we will remove this once the synchronous customization hooks land
  • esm/worker.js: handleMessage (might not need updating as we will remove this once the synchronous customization hooks land

@nodejs/loaders @mcollina @JakobJingleheimer @joyeecheung

Activity

  1. added
    esmIssues and PRs related to the ECMAScript Modules implementation.
    performanceIssues and PRs related to the performance of Node.js.
    on Nov 8, 2024
  2. marco-ippolito commented on Nov 8, 2024

    @marco-ippolito
    Member

    Maybe moving it in the loaders repo would be more appropriate since its a effort that is gonna require different iterations?

  3. mcollina commented on Nov 8, 2024

    @mcollina
    SponsorMember

    This task is better handled by a large group of people, and this repo is more visible. Once the first few steps are done, it can easily be tagged as "good first issue"

  4. added
    loadersIssues and PRs related to ES module loaders.
    on Nov 8, 2024
  5. nomagick commented on Nov 10, 2024

    @nomagick

    I would like to mention my issue here.
    Please check if it's worth fixing.

  6. 0hmX commented on Nov 16, 2024

    @0hmX
    Contributor

    Hi @mcollina and @marco-ippolito,
    Is anyone currently working on any of these issues? I’d love to help resolve a few. Could you recommend a good starting point? I’d like to begin with something low-risk—what would be the best issue to pick?

    Also what is the best method to test if my code is improving performance?

  7. joyeecheung commented on Feb 18, 2025

    @joyeecheung
    Member

    This may be necessary to prevent a race condition like prettier/prettier#17139 (comment)

  8. GeoffreyBooth commented on Mar 9, 2025

    @GeoffreyBooth
    MemberAuthor

    @cu8code Sorry to not notice your comment earlier. If you'd like to help with this effort, you can pick any of the functions listed in the top issue and try to refactor them to be synchronous. The lowest hanging fruit are the ones that are async functions but never actually await anything (perhaps because they used to contain async logic but no longer do, for example). Besides prioritizing the easiest parts, I would also prioritize the hottest code paths: the functions involved in initial load of the most common use case like node app.js where app.js is an ES module. I would make the PRs as small as possible so that any resulting issues can be isolated as narrowly as possible, along the lines of #57390.

  9. marco-ippolito commented on Mar 17, 2025

    @marco-ippolito
    Member
    • esm/fetch_module.js: fetchWithRedirects

    • esm/fetch_module.js: isLocalAddress

    Can be removed since we removed http imports

  10. ntindle commented on Mar 17, 2025

    @ntindle
  11. JakobJingleheimer commented on Apr 2, 2025

    @JakobJingleheimer
  12. mcollina commented on Apr 4, 2025

    @mcollina
    SponsorMember

    #57749 adds everysync as decided in the collab summit.

  13. added a commit that references this issue on Aug 21, 2025
  14. added a commit that references this issue on Sep 20, 2025
  15. github-actions commented on Apr 26, 2026

    @github-actions
    Contributor

    This issue has been marked as stale due to 210 days of inactivity.
    It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.

  16. added
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on Apr 26, 2026
  17. removed
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on Apr 26, 2026
  18. GeoffreyBooth commented on Apr 26, 2026

    @GeoffreyBooth
    MemberAuthor

    WIP: #62530

  19. github-actions commented on Jul 26, 2026

    @github-actions
    Contributor

    This issue has been marked as stale due to 90 days of inactivity.
    It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.

  20. added
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on Jul 26, 2026
  21. added
    never-staleIssues and PRs exempt from automated stale handling.
    and removed
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on Jul 27, 2026
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

    esmIssues and PRs related to the ECMAScript Modules implementation.loadersIssues and PRs related to ES module loaders.never-staleIssues and PRs exempt from automated stale handling.performanceIssues and PRs related to the performance of Node.js.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions