Finding when an API was first added
Run 'git log --all --reverse --oneline -S "methodName" -- docs/api/file.md' to find the first commit adding the method name to documentation. For C++ implementation history, use 'git log --reverse -L :FunctionName:path/to/source.cc'.
API history migration resources
Guide is at 'docs/development/api-history-migration-guide.md'. Style rules are in 'docs/development/style-guide.md' under the 'API History' section. Schema is defined in 'docs/api-history.schema.json'. Linting is run with 'npm run lint:api-history'.
Removed APIs do not need history blocks
APIs that were deprecated and then removed from documentation do not need history blocks in the documentation itself, as the removal is recorded in 'docs/breaking-changes.md'.
API history YAML block placement in Markdown
Place the YAML history block directly after the Markdown header, before parameters. For module-level blocks, place them after the '# moduleName' heading and before the module description quote. For section headers like '## Methods' or '### Instance Methods', do NOT add history blocks.
Promisification as a changes entry
Promisification PRs (e.g., #17355) count as 'changes' entries with the description: 'This method now returns a Promise instead of using a callback function.' These PRs are breaking changes and should be documented in breaking-changes.md.
API history YAML field constraints
The 'added' and 'deprecated' arrays have maxItems of 1, meaning each can contain only a single entry. The 'changes' array can have multiple items. Both 'added' and 'deprecated' entries do not require a description field, but 'changes' entries require a 'description' field.
Finding PRs by keyword search
Use 'git log --grep="keyword" --oneline' to find merge commits that reference PRs by keyword.
Verifying PR targets main branch
Use 'gh pr view <number> --repo electron/electron --json baseRefName' to verify that a PR targets the main branch and is not a backport. Always use the main-branch PR URL in history blocks, not backport PR URLs.
API history YAML block format
The YAML history block must be wrapped in a Markdown HTML comment containing YAML code fence. Structure: start with '<!--', then '```YAML history', followed by history entries (added, deprecated, or changes), then '```', then '-->' to close the comment.
YAML description field special character handling
Wrap description values in double quotes to avoid YAML parsing issues with special characters.
Very early Electron APIs without history blocks
Very early APIs from 2013-2014, such as 'ipcMain.on' and 'ipcRenderer.send', predate GitHub PRs and should not have history blocks. Early Electron APIs from before 2015 may use merge-commit PRs (e.g., 'Merge pull request #534').
Finding breaking changes for cross-referencing
Search 'docs/breaking-changes.md' for the API name to find associated deprecations or removals. Use 'git blame' on the breaking-changes entry to find the associated PR. Add a 'breaking-changes-header' field using the heading ID from breaking-changes.md.
Multiple APIs added in same PR
When multiple APIs were added in the same PR, they all reference the same PR URL in their individual history blocks.
Behavior Changed: NativeImage.toBitmap() normalizes color space in Electron 43
NativeImage.toBitmap() (and its deprecated alias NativeImage.getBitmap()) now normalizes pixel data to sRGB by default. Previously, raw pixel data was returned without color space conversion. To preserve the previous behavior, pass the image's original color space in the colorSpace option. You can also pass colorSpace to convert to any other specific color space with properties: primaries, transfer, matrix, and range.
Behavior Changed: WCO respects native title bar layout on Linux in Electron 43
Frameless windows with Window Controls Overlay (WCO) now adopt the native title bar layout and user settings on Linux. For example, controls will appear on the left side of the frame on RTL systems, and only the close button will be visible by default on GNOME. Depending on the user's desktop environment and configuration, buttons can appear on the left or right side of the frame (or both). To account for all possibilities, use the CSS variables env(titlebar-area-x, 0px) and env(titlebar-area-width, 100%) to constrain your app's title bar content to a safe area.
Behavior Changed: Rounded corners on Linux in Electron 43
Frameless windows default to rounded corners on Linux if the desktop environment supports client-side decorations. This can be configured using the existing roundedCorners option on BrowserWindow, which is now supported on Linux and defaults to true on all platforms.
clipboard module API migration table from old to new API
Migration table from deprecated clipboard API to new W3C-aligned API:
| Old API | New API |
|---------|----------|
| clipboard.availableFormats([type]) | clipboard.read() - iterate through ClipboardItem array and collect types |
| clipboard.clear() | clipboard.clear() (no type parameter) |
| clipboard.clear('selection') (Linux) | clipboard.selection.clear() |
| clipboard.has(format) | clipboard.has(mimetype) returns Promise<boolean> |
| clipboard.has(format, 'selection') (Linux) | clipboard.selection.has(mimetype) returns Promise<boolean> |
| clipboard.read() | clipboard.read() returns Promise<ClipboardItem[]> |
| clipboard.read('selection') (Linux) | clipboard.selection.read() returns Promise<ClipboardItem[]> |
| clipboard.readBookmark() | clipboard.read() with electron application/bookmark custom format |
| clipboard.readBuffer(format) | clipboard.read() with electron application/osclipboard;format="..." custom format |
| clipboard.readBuffer('selection') (Linux) | clipboard.selection.read() with electron application/osclipboard;format="..." |
| clipboard.readFindText() (macOS) | clipboard.read() with electron application/findtext custom format |
| clipboard.readHTML([type]) | clipboard.read() with text/html MIME type |
| clipboard.readImage([type]) | clipboard.read() with image/* MIME type |
| clipboard.readRTF([type]) | clipboard.read() with text/rtf MIME type |
| clipboard.readText() | clipboard.readText() returns Promise<string> |
| clipboard.readText('selection') (Linux) | clipboard.selection.readText() returns Promise<string> |
| clipboard.write(data) | clipboard.write([new ClipboardItem({ [mime]: Blob / string })]) |
| clipboard.write(data, 'selection') (Linux) | clipboard.selection.write([new ClipboardItem({ [mime]: Blob / string })]) |
| clipboard.writeBookmark(title, url[, type]) | clipboard.write() with electron application/bookmark |
| clipboard.writeBuffer(format, buffer[, type]) | clipboard.write() with electron application/osclipboard;format="..." |
| clipboard.writeBuffer(format, buffer, 'selection') (Linux) | clipboard.selection.write() with electron application/osclipboard;format="..." |
| clipboard.writeFindText(text) (macOS) | clipboard.write() with electron application/findtext |
| clipboard.writeHTML(markup[, type]) | clipboard.write() with text/html MIME type |
| clipboard.writeImage(image[, type]) | clipboard.write() with image/* MIME type |
| clipboard.writeRTF(text[, type]) | clipboard.write() with text/rtf MIME type |
| clipboard.writeText(text) | clipboard.writeText(text) returns Promise<void> |
| clipboard.writeText(text, 'selection') (Linux) | clipboard.selection.writeText(text) returns Promise<void> |
API Changed: clipboard module rearchitected to align with W3C Clipboard API
The clipboard module has been rearchitected to align with the W3C Clipboard API. The four read/write methods now all return Promises: (1) clipboard.read() returns Promise<ClipboardItem[]>, each item exposes a types array and getType(type) → Promise<Blob> for lazy retrieval, matching W3C ClipboardItem; (2) clipboard.write(items) returns Promise<void> and accepts an array of ClipboardItem instances constructed via new ClipboardItem({ [mime]: payload }), each payload is Blob | string | Object; (3) clipboard.readText() returns Promise<string>; (4) clipboard.writeText(text) returns Promise<void>. clipboard.has(mimetype) now returns Promise<boolean> and accepts a MIME type instead of a format. The text/uri-list MIME type now maps to the operating system's native file-reference format (CF_HDROP on Windows, NSFilenamesPboardType on macOS, text/uri-list on Linux). Narrowly-scoped helpers and the optional type parameter have been removed. The Linux selection clipboard is now reached through clipboard.selection sub-namespace.
Removed: clipboard module in renderer process in Electron 44
The clipboard module is no longer exposed to renderer processes. It was previously deprecated and is now removed in line with RFC 0019 to close the security risk of granting non-sandboxed renderers direct clipboard access. Renderers should use the navigator.clipboard API to safely work with the system clipboard. If more advanced usage is necessary, expose the necessary helpers from a preload script using the contextBridge API. When using contextBridge, care must be taken to ensure that the clipboard API is not exposed to untrusted content.
Breaking changes categorization types
Breaking changes are categorized using five types: (1) API Changed - an API was changed in a way that code not updated is guaranteed to throw an exception; (2) Behavior Changed - Electron behavior changed, but not necessarily throwing an exception; (3) Default Changed - code depending on the old default may break without necessarily throwing an exception, old behavior can be restored by explicitly specifying the value; (4) Deprecated - an API was marked as deprecated, will continue to function but emit a deprecation warning and be removed in a future release; (5) Removed - an API or feature was removed and is no longer supported.
webview new-window event removed in Electron 22
The new-window event of webview has been removed. Use setWindowOpenHandler on the webContents and communicate back to the renderer via IPC.
Behavior Changed: window.open popups are always resizable in Electron 39
Per current WHATWG spec, the window.open API will now always create a resizable popup window. To restore previous behavior, use webContents.setWindowOpenHandler((details) => { return { action: 'allow', overrideBrowserWindowOptions: { resizable: details.features.includes('resizable=yes') } } }).
Removed: ORIGINAL_XDG_CURRENT_DESKTOP environment variable in Electron 38
Previously, Electron changed the value of XDG_CURRENT_DESKTOP internally to Unity, and stored the original name of the desktop session in a separate variable. XDG_CURRENT_DESKTOP is no longer overridden and now reflects the actual desktop environment.
Removed: plugin-crashed event in Electron 38
The plugin-crashed event has been removed from webContents.
Deprecated: webFrame.findFrameByRoutingId() in Electron 38
The webFrame.findFrameByRoutingId(routingId) function will be removed. You should use webFrame.findFrameByToken(frameToken) instead.
Removed: Pre-macOS 13 login item attributes in Electron 44
Electron 44 removes the option openAsHidden from app.setLoginItemSettings() and the fields openAsHidden, wasOpenedAsHidden and restoreState from the return value of app.getLoginItemSettings(). These only worked on macOS 12 and below. Support for macOS 12 has been dropped.
Behavior Changed: BrowserWindow.IsVisibleOnAllWorkspaces() on Linux in Electron 37
BrowserWindow.IsVisibleOnAllWorkspaces() will now return false on Linux if the window is not currently visible.
Deprecated: NativeImage.getBitmap() in Electron 36
NativeImage.toBitmap() returns a newly-allocated copy of the bitmap. NativeImage.getBitmap() was originally an alternative function that returned the original instead of a copy. This changed when sandboxing was introduced, so both return a copy and are functionally equivalent. Client code should call NativeImage.toBitmap() instead.
Removed: quota type syncable in Session.clearStorageData in Electron 36
When calling Session.clearStorageData(options), the options.quota type syncable is no longer supported because it has been removed from upstream Chromium.
Behavior Changed: chrome.scripting CSS injection matches more fallback frames in Electron 43
Extensions using chrome.scripting.insertCSS() or chrome.scripting.removeCSS() now follow Chrome's behavior when Electron cannot match a frame's URL directly, such as with about:blank or data: frames. If the extension has access to the page that created the frame, CSS may now be inserted into or removed from those fallback frames as well. Apps or extensions that relied on Electron skipping those frames should narrow their injection target, frame IDs, or match patterns.
Removed: Windows 32-bit and Linux 32-bit ARM support in Electron 44
Electron no longer publishes prebuilt binaries for 32-bit platforms: Windows x86 (win32-ia32) and Linux ARM (linux-armv7l). All related release artifacts (chromedriver, mksnapshot, ffmpeg, and the Windows x86 node.lib on the Electron headers CDN) are no longer published either. Older versions of Electron will continue to support these platforms, but Electron v44.0.0 and higher will only be published for 64-bit platforms. Once the v43 series reaches end of life in January 2027, these 32-bit platforms will no longer be supported.
Behavior Changed: MacOS dSYM files compression in Electron 40
Debug symbols for MacOS (dSYM) now use xz compression in order to handle larger file sizes. dsym.zip files are now dsym.tar.xz files. End users using debug symbols may need to update their zip utilities.
Deprecated: showHiddenFiles in Dialogs on Linux in Electron 41
The showHiddenFiles property in dialogs will still be honored on macOS and Windows, but support on Linux will be removed in a future version of Electron. GTK intends for this to be a user choice rather than an app choice and has removed the API to do this programmatically.
Removed: Unity desktop environment support on Linux in Electron 44
Unity has not been the default desktop environment in Ubuntu LTS since version 16.04, which is not supported by current versions of Electron. Electron will no longer offer unique functionality on Unity but will continue to run if installed in a newer distribution. Electron supports modern Freedesktop standards on Linux rather than APIs which only work in specific environments. The API app.isUnityRunning() has been removed. Some Unity-specific APIs no longer function on Linux but remain supported on other platforms: app.setBadgeCount(count) and app.badgeCount (macOS only), BaseWindow.setProgressBar(progress) and BrowserWindow.setProgressBar(progress) (Windows and macOS only).
Planned breaking API changes (44.0) - net.request rejects frame destinations without navigate mode
net.request now rejects requests where Sec-Fetch-Dest is document, frame, iframe, or fencedframe unless Sec-Fetch-Mode is also set to navigate. This matches Chromium's enforcement that frame-type request destinations must be navigations. Apps that explicitly set one of these Sec-Fetch-Dest values on a net.request must also set Sec-Fetch-Mode to navigate.
Behavior Changed: Cookie change cause values in Electron 41
The cookie change cause in the cookie 'changed' event has been updated. When a new cookie is set, the change cause is 'inserted'. When a cookie is deleted, the change cause remains 'explicit'. When the cookie being set is identical to an existing one (same name, domain, path, and value, with no actual changes), the change cause is 'inserted-no-change-overwrite'. When the value of the cookie being set remains unchanged but some of its attributes are updated (such as the expiration attribute), the change cause is 'inserted-no-value-change-overwrite'.
Behavior Changed: PDFs no longer create separate WebContents in Electron 41
Previously, PDF resources created a separate guest WebContents for rendering. Now, PDFs are rendered within the same WebContents instead. If you have code to detect PDF resources, use the frame tree instead of WebContents. Under the hood, Chromium enabled a feature that changes PDFs to use out-of-process iframes (OOPIFs) instead of the MimeHandlerViewGuest extension.
Planned breaking API changes (44.0) - ANGLE is statically linked on all platforms
ANGLE is now statically linked into the Electron binary on all platforms, matching upstream Chromium. The libEGL.(so|dylib|dll) and libGLESv2.(so|dylib|dll) libraries are no longer shipped in the distribution. Apps that replaced or managed their own ANGLE versions by swapping out these libraries can no longer do so. Additionally, because ANGLE is now part of the Electron binary, it is loaded into every process rather than only the GPU process, which may surface regressions in unusual configurations.
Deprecated: Passing array hslShift to nativeImage.createFromNamedImage() in Electron 42
Passing only an array hslShift to nativeImage.createFromNamedImage() is deprecated. You should now pass an options object with an hslShift property instead. The deprecated syntax is nativeImage.createFromNamedImage(imageName, [0, 1, -1]); replace with nativeImage.createFromNamedImage(imageName, { hslShift: [0, 1, -1] }).
Deprecated: clipboard API access from renderer processes in Electron 40
Using the clipboard API directly in the renderer process is deprecated. If you want to call this API from a renderer process, place the API call in your preload script and expose it using the contextBridge API.
Removed: quotas object from Session.clearStorageData in Electron 42
When calling Session.clearStorageData(options), the options.quotas object is no longer supported because it has been removed from upstream Chromium.
Deprecated: --host-rules command line switch in Electron 39
Chromium is deprecating the --host-rules switch. You should use --host-resolver-rules instead.
Removed: macOS 12 support in Electron 44
macOS 12 (Monterey) is no longer supported by Chromium. Older versions of Electron will continue to run on Monterey, but macOS 13 (Ventura) or later will be required to run Electron v44.0.0 and higher.
Behavior Changed: NSAudioCaptureUsageDescription required for desktopCapturer in Electron 39
Per Chromium update which enables Apple's newer CoreAudio Tap API by default, you now must have NSAudioCaptureUsageDescription defined in your Info.plist to use desktopCapturer on macOS 14.2 and higher. Electron's desktopCapturer will create a dead audio stream if the new permission is absent however no errors or warnings will occur. To restore previous behavior, use app.commandLine.appendSwitch('disable-features', 'MacCatapLoopbackAudioForScreenShare').
Behavior Changed: shared texture OSR paint event data structure in Electron 39
When using shared texture offscreen rendering feature, the paint event now emits a more structured object. It moves the sharedTextureHandle, planes, modifier into a unified handle property. See the OffscreenSharedTexture API structure for more details.
Removed: ELECTRON_OZONE_PLATFORM_HINT environment variable in Electron 38
The default value of the --ozone-platform flag changed to auto. Electron now defaults to running as a native Wayland app when launched in a Wayland session (when XDG_SESSION_TYPE=wayland). Users can force XWayland by passing --ozone-platform=x11.
Behavior Changed: electron npm package download in Electron 42
Previously, the electron npm package would download the Electron binary from the repository's GitHub Releases in the package's postinstall script. With recent supply chain security attacks against the npm ecosystem using postinstall scripts, Electron now downloads itself dynamically the first time that its main bin script is run (e.g. via npx electron). This change allows using Electron with the npm --ignore-scripts flag. If you need to download the Electron binary on-demand, call the install-electron script, which contains the exact same code from the former postinstall script. Use ELECTRON_INSTALL_ARCH and ELECTRON_INSTALL_PLATFORM environment variables to test changes across platforms or architectures. The ELECTRON_SKIP_BINARY_DOWNLOAD environment variable is no longer supported.
Removed: macOS 11 support in Electron 38
macOS 11 (Big Sur) is no longer supported by Chromium. Older versions of Electron will continue to run on Big Sur, but macOS 12 (Monterey) or later will be required to run Electron v38.0.0 and higher.
Behavior Changed: Offscreen rendering device scale factor default in Electron 42
Previously, offscreen rendering (OSR) used the primary display's device scale factor for rendering, which made the output frame size vary across users. Developers had to manually calculate the correct size using screen.getPrimaryDisplay().scaleFactor. The optional property webPreferences.offscreen.deviceScaleFactor was provided to specify a custom value when creating an OSR window. Initially, if the property is not set, it defaults to the primary display's scale factor (preserving the old behavior). Starting from Electron 42, the default will change to a constant value of 1.0 for more consistent output sizes.
Deprecated: webFrame.routingId property in Electron 38
The routingId property will be removed from webFrame objects. You should use webFrame.frameToken instead.
Behavior Changed: macOS notifications use UNNotification API in Electron 42
Electron has migrated from the deprecated NSUserNotification API to the UNNotification API on macOS. The new API requires that an application be code-signed in order for notifications to be displayed. If an application is not code-signed, notifications will emit a failed event on the Notification object.
Utility Process unhandled rejection behavior change in Electron 37
Utility Processes will now warn with an error message when an unhandled rejection occurs instead of crashing the process. To restore the previous behavior, use: process.on('unhandledRejection', () => { process.exit(1) }).
Behavior Changed: process.exit() in utility process in Electron 37
Calling process.exit() in a utility process will now kill the utility process synchronously. This brings the behavior of process.exit() in line with Node.js behavior. Potential implications include console.log() calls before process.exit() may not output.
Behavior Changed: WebUSB and WebSerial Blocklist Support in Electron 37
WebUSB and Web Serial now support the WebUSB Blocklist and Web Serial Blocklist used by Chromium. To disable these, users can pass disable-usb-blocklist and disable-serial-blocklist as command line flags.
Behavior Changed: Dialog methods default to Downloads directory in Electron 43
The defaultPath option for the following methods now defaults to the user's Downloads folder (or their home directory if Downloads doesn't exist) when not explicitly provided: dialog.showOpenDialog, dialog.showOpenDialogSync, dialog.showSaveDialog, dialog.showSaveDialogSync. Previously, when no defaultPath was provided, the underlying OS file dialog would determine the initial directory. Now Electron explicitly sets the initial directory to Downloads, which also means the OS will no longer track and restore the last-used directory between dialog invocations. To preserve the old behavior, track the last-used directory yourself and pass it as defaultPath.
Behavior Changed: app.commandLine converts to lowercase in Electron 36
app.commandLine will convert upper-case switches and arguments to lowercase. app.commandLine was only meant to handle chromium switches (which aren't case-sensitive) and switches passed via app.commandLine will not be passed down to any of the child processes. If you were using app.commandLine to control the behavior of the main process, use process.argv instead.
Planned breaking API changes (44.0) - webContents may be null in select-client-certificate
The app 'select-client-certificate' event is now also emitted for requests made via the net module and for utility processes created with respondToAuthRequestsFromMainProcess: true. For these requests the webContents argument is null. Previously the event was only emitted for WebContents requests and the argument was always non-null. When the event is not handled or event.preventDefault() is not called, Electron uses the first matching client certificate from the platform certificate store. Previously net requests to a server that requested a client certificate failed with ERR_SSL_CLIENT_AUTH_CERT_NEEDED. To opt out, handle the event and call callback() with no argument to continue without a client certificate.
Removed: isDefault and status properties on PrinterInfo in Electron 36
The isDefault and status properties have been removed from the PrinterInfo Object because they have been removed from upstream Chromium.
Planned breaking API changes (44.0) - window.open() children get their own sandboxed process
window.open() child normally shares its opener's renderer process. Previously a child opened from an unsandboxed (e.g. nodeIntegration: true) window silently ran in that unsandboxed process even though webContents.getLastWebPreferences() reported sandbox: true for it. Now the child's own web preferences decide the sandbox state. When the state differs from the opener's process, the child is created in a new process with no opener relationship: window.open() returns null in the opener and window.opener is null in the child, matching window.open(url, '_blank', 'noopener'). A warning is logged to the opener's console. Child windows default to sandboxed, so a child opened from an unsandboxed window is now isolated in its own sandboxed process by default. To restore the previous behavior of sharing the opener's unsandboxed process, opt in explicitly from webContents.setWindowOpenHandler with overrideBrowserWindowOptions.webPreferences.sandbox: false or setting nodeIntegration: true.
app.getAppMemoryInfo replaced with app.getAppMetrics in Electron 3
app.getAppMemoryInfo has been replaced with app.getAppMetrics.