CodeVetter · Repo Unpack · System map
electron/electron
Electron is a Chromium content-API embedder: platform entry points (shell/app/electron_main_*.cc) create an ElectronMainDelegate that plugs Electron's content clients into content::ContentMain. The browser (main) process lives in shell/browser, renderers in shell/renderer, shared code in shell/common, and a separate utility-process client in shell/utility plus shell/services/node. On top of the C++ core sits a TypeScript layer in lib/ that is bundled per execution context (browser, renderer, worker, webview, isolated_renderer, node, utility) and compiled into the binary. Build is GN/Ninja driven by BUILD.gn and filenames.gni, with dependency versions pinned in DEPS and upstream modifications carried as patch queues in patches/.
- Each platform has a thin main() — shell/app/electron_main_linux.cc line 49 — that hands off to content::ContentMain with an ElectronMainDelegate; the delegate implements BasicStartupComplete, PreSandboxStartup, PreBrowserMain and the CreateContent*Client factory methods.
- The browser-process composition root is ElectronBrowserMainParts: its constructor wires BrowserProcessImpl, NodeBindings, ElectronBindings and the Browser singleton, and PostEarlyInitialization() creates the V8 isolate via JavascriptEnvironment, initializes Node, and loads the app package.
- ElectronMainDelegate::CreateContentRendererClient selects between ElectronSandboxedRendererClient and ElectronRendererClient based on IsSandboxEnabled(command_line), so the sandbox decision happens per child-process launch.
- The JS layer in lib/ is compiled into seven self-contained bundles (browser, renderer, worker, webview, isolated_renderer, node, utility) by build/bundle/bundle.mjs using rolldown, driven by the per-target flags in build/bundle/targets.mjs.
- Native modules are exposed to JS through process._linkedBinding: node_bindings.cc declares the binding names in the ELECTRON_BROWSER_BINDINGS / ELECTRON_COMMON_BINDINGS / ELECTRON_RENDERER_BINDINGS macros, and each C++ file registers itself with NODE_LINKED_BINDING_CONTEXT_AWARE (e.g. electron_browser_app in electron_api_app.cc).
- The 'electron' npm module object is assembled lazily: lib/browser/api/exports/electron.ts calls defineProperties over commonModuleList + browserModuleList, where each entry is { name, loader } with a deferred require().
- require('electron'), 'electron/main', 'electron/renderer', 'electron/common' and 'electron/utility' are module aliases installed by lib/common/init.ts via fake entries in Module._cache and a Module._resolveFilename override.
- Dependencies are pinned in DEPS: chromium_version 155.0.8046.0, node_version v24.21.0, plus squirrel.mac, sparkle, nan and others; gclient applies the patch queue because 'apply_patches': True.
- patches/config.json maps 13 patch directories (chromium, boringssl, devtools_frontend, ffmpeg, v8, node, nan, libaddressinput, perfetto, squirrel.mac, webrtc, sqlite, angle) onto target repos under src/.
- Build configuration is GN: BUILD.gn (~2200 lines) defines the electron targets including the electron_fuses action that generates fuses.h/fuses.cc from build/fuses/fuses.json5; per-build args live in build/args/{all,testing,release}.gn.
- If no app is supplied, resources/default_app.asar provides a fallback app (default_app/) that parses CLI args, can open a file/URL/package directory, prints --version/--abi, or starts a REPL with lazy Electron builtins.
- The published npm package (npm/) is a thin downloader: index.js reads path.txt for the executable name, supports ELECTRON_OVERRIDE_DIST_PATH, and runs install.js to fetch the binary.
- asar archives are supported at two levels: shell/common/asar implements the archive reader used by C++ (LoadAppPackage reads package.json through asar::ReadFileToString), and lib/node/asar-fs-wrapper.ts monkey-patches the fs module so Node can read inside .asar files.