Use synchronous hooks for ESM ASAR resolution - #331731
Draft
Dmitriy Vasyura (dmitrivMS) wants to merge 2 commits into
Draft
Use synchronous hooks for ESM ASAR resolution#331731Dmitriy Vasyura (dmitrivMS) wants to merge 2 commits into
Dmitriy Vasyura (dmitrivMS) wants to merge 2 commits into
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot started reviewing on behalf of
Dmitriy Vasyura (dmitrivMS)
August 19, 2026 23:37
View session
Contributor
There was a problem hiding this comment.
Pull request overview
Migrates Electron ASAR resolution to synchronous Node.js hooks, reducing startup overhead while preserving existing resolution behavior.
Changes:
- Replaces
module.registerwith synchronousmodule.registerHooks. - Preserves ASAR fallback, package self-reference, tracing, and
original-fsmapping. - Bypasses CommonJS resolution to retain existing
require()behavior.
Show a summary per file
| File | Description |
|---|---|
src/bootstrap-esm.ts |
Implements synchronous, in-process ASAR resolution hooks. |
Review details
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
- Files reviewed: 1/1 changed files
- Comments generated: 0
- Review effort level: Balanced
Dmitriy Vasyura (dmitrivMS)
removed the request for review
from Robo (deepak1556)
August 20, 2026 17:01
Mohammad javad Dianat (dianatofficial)
left a comment
There was a problem hiding this comment.
Great catch on this edge case. Fallback logic is robust.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Background
VS Code installs a custom ESM resolution hook in Electron processes to:
fsimports to Electron's ASAR-unawareoriginal-fs.node_modules.asar.node_modules.The hook currently uses Node's asynchronous
module.register. Node runs those hooks on a dedicated loader worker, while static module linking synchronously waits for the worker.This became visible while investigating Windows startup performance after Agent Host began prewarming during
WorkbenchPhase.BlockRestore. An Agent Host utility-process profile attributed:node:internal/modules/esm/hooks#makeSyncRequestMost
makeSyncRequesttime was the main Agent Host thread waiting synchronously for the loader worker during static module linking.Node 24 provides
module.registerHooks, which runs synchronous hooks in-process. VS Code already uses this API in the extension host.Change
Port the existing ASAR resolver to
module.registerHooks.Resolution behavior remains the same:
fsmaps tonode:original-fs.node_modules.asar.exports,main, and ESM import conditions.VSCODE_ASAR_TRACEremains available.Synchronous hooks also apply to CommonJS resolution, unlike asynchronous hooks. The resolver therefore explicitly bypasses contexts containing the
requirecondition, preserving existingrequire()andcreateRequire()behavior.Startup scenario improvement
The final A/B uses two fully bundled current-source Windows desktop applications:
out/directories differ only by this changeEach app received three warmups followed by 30 measured starts. Every individual start was interleaved, alternating A/B and B/A order. The standard performance scenario opens a deterministic local folder and one text file with extensions, updates, experiments, workspace trust, GPU, telemetry, and crash reporting disabled.
The phase measurements overlap and should not be summed. The conservative end-to-end startup win is 18.5 ms on this Windows host.
Improvements to other scenarios
The same bootstrap is shared by Electron main/CLI and
bootstrap-forkprocesses such as Agent Host, extension host, shared/process services, file watchers, and terminal hosts.Measured improvements in the packaged A/B:
Agent Host launch timing relative to workbench startup is unchanged (+4 ms, interval includes zero), while protocol connection becomes substantially faster. This preserves the early prewarm behavior required by #324330 rather than moving work after startup.
The packaged CLI also starts successfully through the synchronous hook.
Compatibility / lack of regressions
Validation covered the behavioral differences between asynchronous and synchronous Node hooks:
import('fs')resolves tooriginal-fs.require('fs')remains the normal Electron/Node module.--versionsucceeds.Tests:
The diff-worker coverage is relevant because synchronous hooks are process-local and are not inherited by worker threads; the existing worker imports only built-ins/internal files and continues to pass.
Two independent implementation/diff reviews found no significant correctness or compatibility issue.
Commands