CodeVetter · Repo Unpack · Extension points
electron/electron
New APIs plug in at three layers: a C++ binding registered via NODE_LINKED_BINDING_CONTEXT_AWARE plus a name in the ELECTRON_*_BINDINGS macros, a JS wrapper added to the appropriate lib/<proc>/api/module-list.ts, and a docs/api/*.md page that generates the .d.ts. Apps extend Electron through protocol.handle/registerSchemesAsPrivileged, session partitions and preload-script registration, ipcMain/ipcRenderer channels, utilityProcess.fork, and (for embedders) build-time fuses and GN buildflags. docs/development/creating-api.md documents the recipe.
- To add a main-process module: add { name, loader } to browserModuleList in lib/browser/api/module-list.ts (alphabetical, with a matching module-keys update noted in the file's TODO), implement lib/browser/api/<name>.ts, and it appears on require('electron') via defineProperties.
- To add a native binding: register Initialize() with NODE_LINKED_BINDING_CONTEXT_AWARE(electron_<proc>_<name>, Initialize) at file scope and add the name to the matching ELECTRON_*_BINDINGS macro in node_bindings.cc; JS reaches it via process._linkedBinding('electron_<proc>_<name>').
- docs/development/creating-api.md is the canonical recipe for new APIs; the docs page's YAML 'history' front-matter is schema-validated and feeds electron.d.ts generation via create-api-json.mjs + electron-typescript-definitions.
- protocol.registerSchemesAsPrivileged (must run before app ready, per spec/index.js usage) + session.protocol.handle/unhandle/isProtocolHandled let apps mint custom URL schemes with privileges (standard, secure, stream, corsEnabled, supportFetchAPI, allowServiceWorkers).
- session.fromPartition/fromPath create isolated storage/network contexts; registerPreloadScript registers frame- or service-worker-scoped preloads (superseding getPreloads/setPreloads which are deprecation shims).
- session.extensions.loadExtension (Chromium extensions support, ENABLE_ELECTRON_EXTENSIONS buildflag) is the app-facing extension point for MV2-style extensions; old session.loadExtension calls are rerouted with deprecation warnings.
- ipcMain.handle/on and ipcRenderer.invoke/send are the app-level RPC extension point; MessageChannelMain/MessagePortMain support transferable ports, and ipcMainServiceWorker covers service-worker targets.
- utilityProcess.fork(modulePath, args, opts) is the supported way to run app JS in a dedicated process with postMessage messaging — replacing child_process.fork when the runAsNode fuse is off.
- GN buildflags (buildflags/buildflags.gni) gate major subsystems — ENABLE_ELECTRON_EXTENSIONS, ENABLE_BUILTIN_SPELLCHECKER, ENABLE_PDF_VIEWER, ENABLE_PRINTING, ENABLE_PLUGINS — and are exposed to JS at runtime via electron_common_features binding (features.cc).
- Fuses are the distributor-facing extension mechanism: build/fuses/fuses.json5 is the schema (with a 'never remove, mark removed r' rule and _version field), generated into fuses.h/fuses.cc by build/fuses/build.py during the electron_fuses GN action; the @electron/fuses npm package flips them in shipped binaries.
- New webview-exposed behaviors plug into the GUEST_VIEW_MANAGER_* internal channels plus the syncMethods/asyncMethods/properties tables in lib/common/web-view-methods.ts and the event list in lib/browser/web-view-events.ts.
- New patch targets are added by extending patches/config.json with a {patch_dir, repo} pair — the queue is applied by e sync / apply-patches.yml and exported by e patches <target>.
- The bundle pipeline itself is extensible: adding a lib/<name>/init.ts plus a targets.mjs entry produces a new baked-in JS context, with knobs for Node availability, electron-module aliasing, node-globals capture and init wrapping. (inferred)