# Breaking Changes Breaking changes will be documented here, and deprecation warnings added to JS code where possible, at least [one major version](tutorial/electron-versioning.md#semver) before the change is made. ## `FIXME` comments The `FIXME` string is used in code comments to denote things that should be fixed for future releases. See https://github.com/electron/electron/search?q=fixme ## Planned Breaking API Changes (9.0) ### `.getWebContents()` This API, which was deprecated in Electron 8.0, is now removed. ```js // Removed in Electron 9.0 webview.getWebContents() // Replace with const { remote } = require('electron') remote.webContents.fromId(webview.getWebContentsId()) ``` ### `webFrame.setLayoutZoomLevelLimits()` Chromium has removed support for changing the layout zoom level limits, and it is beyond Electron's capacity to maintain it. The function was deprecated in Electron 8.x, and has been removed in Electron 9.x. The layout zoom level limits are now fixed at a minimum of 0.25 and a maximum of 5.0, as defined [here](https://chromium.googlesource.com/chromium/src/+/938b37a6d2886bf8335fc7db792f1eb46c65b2ae/third_party/blink/common/page/page_zoom.cc#11). ### Sending non-JS objects over IPC now throws an exception In Electron 8.0, IPC was changed to use the Structured Clone Algorithm, bringing significant performance improvements. To help ease the transition, the old IPC serialization algorithm was kept and used for some objects that aren't serializable with Structured Clone. In particular, DOM objects (e.g. `Element`, `Location` and `DOMMatrix`), Node.js objects backed by C++ classes (e.g. `process.env`, some members of `Stream`), and Electron objects backed by C++ classes (e.g. `WebContents`, `BrowserWindow` and `WebFrame`) are not serializable with Structured Clone. Whenever the old algorithm was invoked, a deprecation warning was printed. In Electron 9.0, the old serialization algorithm has been removed, and sending such non-serializable objects will now throw an "object could not be cloned" error. ## Planned Breaking API Changes (8.0) ### Values sent over IPC are now serialized with Structured Clone Algorithm The algorithm used to serialize objects sent over IPC (through `ipcRenderer.send`, `ipcRenderer.sendSync`, `WebContents.send` and related methods) has been switched from a custom algorithm to V8's built-in [Structured Clone Algorithm][SCA], the same algorithm used to serialize messages for `postMessage`. This brings about a 2x performance improvement for large messages, but also brings some breaking changes in behavior. - Sending Functions, Promises, WeakMaps, WeakSets, or objects containing any such values, over IPC will now throw an exception, instead of silently converting the functions to `undefined`. ```js // Previously: ipcRenderer.send('channel', { value: 3, someFunction: () => {} }) // => results in { value: 3 } arriving in the main process // From Electron 8: ipcRenderer.send('channel', { value: 3, someFunction: () => {} }) // => throws Error("() => {} could not be cloned.") ``` - `NaN`, `Infinity` and `-Infinity` will now be correctly serialized, instead of being converted to `null`. - Objects containing cyclic references will now be correctly serialized, instead of being converted to `null`. - `Set`, `Map`, `Error` and `RegExp` values will be correctly serialized, instead of being converted to `{}`. - `BigInt` values will be correctly serialized, instead of being converted to `null`. - Sparse arrays will be serialized as such, instead of being converted to dense arrays with `null`s. - `Date` objects will be transferred as `Date` objects, instead of being converted to their ISO string representation. - Typed Arrays (such as `Uint8Array`, `Uint16Array`, `Uint32Array` and so on) will be transferred as such, instead of being converted to Node.js `Buffer`. - Node.js `Buffer` objects will be transferred as `Uint8Array`s. You can convert a `Uint8Array` back to a Node.js `Buffer` by wrapping the underlying `ArrayBuffer`: ```js Buffer.from(value.buffer, value.byteOffset, value.byteLength) ``` Sending any objects that aren't native JS types, such as DOM objects (e.g. `Element`, `Location`, `DOMMatrix`), Node.js objects (e.g. `process.env`, `Stream`), or Electron objects (e.g. `WebContents`, `BrowserWindow`, `WebFrame`) is deprecated. In Electron 8, these objects will be serialized as before with a DeprecationWarning message, but starting in Electron 9, sending these kinds of objects will throw a 'could not be cloned' error. [SCA]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm ### `.getWebContents()` This API is implemented using the `remote` module, which has both performance and security implications. Therefore its usage should be explicit. ```js // Deprecated webview.getWebContents() // Replace with const { remote } = require('electron') remote.webContents.fromId(webview.getWebContentsId()) ``` However, it is recommended to avoid using the `remote` module altogether. ```js // main const { ipcMain, webContents } = require('electron') const getGuestForWebContents = (webContentsId, contents) => { const guest = webContents.fromId(webContentsId) if (!guest) { throw new Error(`Invalid webContentsId: ${webContentsId}`) } if (guest.hostWebContents !== contents) { throw new Error(`Access denied to webContents`) } return guest } ipcMain.handle('openDevTools', (event, webContentsId) => { const guest = getGuestForWebContents(webContentsId, event.sender) guest.openDevTools() }) // renderer const { ipcRenderer } = require('electron') ipcRenderer.invoke('openDevTools', webview.getWebContentsId()) ``` ### `webFrame.setLayoutZoomLevelLimits()` Chromium has removed support for changing the layout zoom level limits, and it is beyond Electron's capacity to maintain it. The function will emit a warning in Electron 8.x, and cease to exist in Electron 9.x. The layout zoom level limits are now fixed at a minimum of 0.25 and a maximum of 5.0, as defined [here](https://chromium.googlesource.com/chromium/src/+/938b37a6d2886bf8335fc7db792f1eb46c65b2ae/third_party/blink/common/page/page_zoom.cc#11). ## Planned Breaking API Changes (7.0) ### Node Headers URL This is the URL specified as `disturl` in a `.npmrc` file or as the `--dist-url` command line flag when building native Node modules. Both will be supported for the foreseeable future but it is recommended that you switch. Deprecated: https://atom.io/download/electron Replace with: https://electronjs.org/headers ### `session.clearAuthCache(options)` The `session.clearAuthCache` API no longer accepts options for what to clear, and instead unconditionally clears the whole cache. ```js // Deprecated session.clearAuthCache({ type: 'password' }) // Replace with session.clearAuthCache() ``` ### `powerMonitor.querySystemIdleState` ```js // Removed in Electron 7.0 powerMonitor.querySystemIdleState(threshold, callback) // Replace with synchronous API const idleState = getSystemIdleState(threshold) ``` ### `powerMonitor.querySystemIdleTime` ```js // Removed in Electron 7.0 powerMonitor.querySystemIdleTime(callback) // Replace with synchronous API const idleTime = getSystemIdleTime() ``` ### webFrame Isolated World APIs ```js // Removed in Electron 7.0 webFrame.setIsolatedWorldContentSecurityPolicy(worldId, csp) webFrame.setIsolatedWorldHumanReadableName(worldId, name) webFrame.setIsolatedWorldSecurityOrigin(worldId, securityOrigin) // Replace with webFrame.setIsolatedWorldInfo( worldId, { securityOrigin: 'some_origin', name: 'human_readable_name', csp: 'content_security_policy' }) ``` ### Removal of deprecated `marked` property on getBlinkMemoryInfo This property was removed in Chromium 77, and as such is no longer available. ### `webkitdirectory` attribute for `` The `webkitdirectory` property on HTML file inputs allows them to select folders. Previous versions of Electron had an incorrect implementation where the `event.target.files` of the input returned a `FileList` that returned one `File` corresponding to the selected folder. As of Electron 7, that `FileList` is now list of all files contained within the folder, similarly to Chrome, Firefox, and Edge ([link to MDN docs](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/webkitdirectory)). As an illustration, take a folder with this structure: ```console folder ├── file1 ├── file2 └── file3 ``` In Electron <=6, this would return a `FileList` with a `File` object for: ```console path/to/folder ``` In Electron 7, this now returns a `FileList` with a `File` object for: ```console /path/to/folder/file3 /path/to/folder/file2 /path/to/folder/file1 ``` Note that `webkitdirectory` no longer exposes the path to the selected folder. If you require the path to the selected folder rather than the folder contents, see the `dialog.showOpenDialog` API ([link](https://github.com/electron/electron/blob/master/docs/api/dialog.md#dialogshowopendialogbrowserwindow-options)). ## Planned Breaking API Changes (6.0) ### `win.setMenu(null)` ```js // Deprecated win.setMenu(null) // Replace with win.removeMenu() ``` ### `contentTracing.getTraceBufferUsage()` ```js // Deprecated contentTracing.getTraceBufferUsage((percentage, value) => { // do something }) // Replace with contentTracing.getTraceBufferUsage().then(infoObject => { // infoObject has percentage and value fields }) ``` ### `electron.screen` in renderer process ```js // Deprecated require('electron').screen // Replace with require('electron').remote.screen ``` ### `require` in sandboxed renderers ```js // Deprecated require('child_process') // Replace with require('electron').remote.require('child_process') // Deprecated require('fs') // Replace with require('electron').remote.require('fs') // Deprecated require('os') // Replace with require('electron').remote.require('os') // Deprecated require('path') // Replace with require('electron').remote.require('path') ``` ### `powerMonitor.querySystemIdleState` ```js // Deprecated powerMonitor.querySystemIdleState(threshold, callback) // Replace with synchronous API const idleState = getSystemIdleState(threshold) ``` ### `powerMonitor.querySystemIdleTime` ```js // Deprecated powerMonitor.querySystemIdleTime(callback) // Replace with synchronous API const idleTime = getSystemIdleTime() ``` ### `app.enableMixedSandbox` ```js // Deprecated app.enableMixedSandbox() ``` Mixed-sandbox mode is now enabled by default. ### `Tray` Under macOS Catalina our former Tray implementation breaks. Apple's native substitute doesn't support changing the highlighting behavior. ```js // Deprecated tray.setHighlightMode(mode) // API will be removed in v7.0 without replacement. ``` ## Planned Breaking API Changes (5.0) ### `new BrowserWindow({ webPreferences })` The following `webPreferences` option default values are deprecated in favor of the new defaults listed below. | Property | Deprecated Default | New Default | |----------|--------------------|-------------| | `contextIsolation` | `false` | `true` | | `nodeIntegration` | `true` | `false` | | `webviewTag` | `nodeIntegration` if set else `true` | `false` | E.g. Re-enabling the webviewTag ```js const w = new BrowserWindow({ webPreferences: { webviewTag: true } }) ``` ### `nativeWindowOpen` Child windows opened with the `nativeWindowOpen` option will always have Node.js integration disabled, unless `nodeIntegrationInSubFrames` is `true. ### Privileged Schemes Registration Renderer process APIs `webFrame.setRegisterURLSchemeAsPrivileged` and `webFrame.registerURLSchemeAsBypassingCSP` as well as browser process API `protocol.registerStandardSchemes` have been removed. A new API, `protocol.registerSchemesAsPrivileged` has been added and should be used for registering custom schemes with the required privileges. Custom schemes are required to be registered before app ready. ### webFrame Isolated World APIs ```js // Deprecated webFrame.setIsolatedWorldContentSecurityPolicy(worldId, csp) webFrame.setIsolatedWorldHumanReadableName(worldId, name) webFrame.setIsolatedWorldSecurityOrigin(worldId, securityOrigin) // Replace with webFrame.setIsolatedWorldInfo( worldId, { securityOrigin: 'some_origin', name: 'human_readable_name', csp: 'content_security_policy' }) ``` ## `webFrame.setSpellCheckProvider` The `spellCheck` callback is now asynchronous, and `autoCorrectWord` parameter has been removed. ```js // Deprecated webFrame.setSpellCheckProvider('en-US', true, { spellCheck: (text) => { return !spellchecker.isMisspelled(text) } }) // Replace with webFrame.setSpellCheckProvider('en-US', { spellCheck: (words, callback) => { callback(words.filter(text => spellchecker.isMisspelled(text))) } }) ``` ## Planned Breaking API Changes (4.0) The following list includes the breaking API changes made in Electron 4.0. ### `app.makeSingleInstance` ```js // Deprecated app.makeSingleInstance((argv, cwd) => { /* ... */ }) // Replace with app.requestSingleInstanceLock() app.on('second-instance', (event, argv, cwd) => { /* ... */ }) ``` ### `app.releaseSingleInstance` ```js // Deprecated app.releaseSingleInstance() // Replace with app.releaseSingleInstanceLock() ``` ### `app.getGPUInfo` ```js app.getGPUInfo('complete') // Now behaves the same with `basic` on macOS app.getGPUInfo('basic') ``` ### `win_delay_load_hook` When building native modules for windows, the `win_delay_load_hook` variable in the module's `binding.gyp` must be true (which is the default). If this hook is not present, then the native module will fail to load on Windows, with an error message like `Cannot find module`. See the [native module guide](/docs/tutorial/using-native-node-modules.md) for more. ## Breaking API Changes (3.0) The following list includes the breaking API changes in Electron 3.0. ### `app` ```js // Deprecated app.getAppMemoryInfo() // Replace with app.getAppMetrics() // Deprecated const metrics = app.getAppMetrics() const { memory } = metrics[0] // Deprecated property ``` ### `BrowserWindow` ```js // Deprecated let optionsA = { webPreferences: { blinkFeatures: '' } } let windowA = new BrowserWindow(optionsA) // Replace with let optionsB = { webPreferences: { enableBlinkFeatures: '' } } let windowB = new BrowserWindow(optionsB) // Deprecated window.on('app-command', (e, cmd) => { if (cmd === 'media-play_pause') { // do something } }) // Replace with window.on('app-command', (e, cmd) => { if (cmd === 'media-play-pause') { // do something } }) ``` ### `clipboard` ```js // Deprecated clipboard.readRtf() // Replace with clipboard.readRTF() // Deprecated clipboard.writeRtf() // Replace with clipboard.writeRTF() // Deprecated clipboard.readHtml() // Replace with clipboard.readHTML() // Deprecated clipboard.writeHtml() // Replace with clipboard.writeHTML() ``` ### `crashReporter` ```js // Deprecated crashReporter.start({ companyName: 'Crashly', submitURL: 'https://crash.server.com', autoSubmit: true }) // Replace with crashReporter.start({ companyName: 'Crashly', submitURL: 'https://crash.server.com', uploadToServer: true }) ``` ### `nativeImage` ```js // Deprecated nativeImage.createFromBuffer(buffer, 1.0) // Replace with nativeImage.createFromBuffer(buffer, { scaleFactor: 1.0 }) ``` ### `process` ```js // Deprecated const info = process.getProcessMemoryInfo() ``` ### `screen` ```js // Deprecated screen.getMenuBarHeight() // Replace with screen.getPrimaryDisplay().workArea ``` ### `session` ```js // Deprecated ses.setCertificateVerifyProc((hostname, certificate, callback) => { callback(true) }) // Replace with ses.setCertificateVerifyProc((request, callback) => { callback(0) }) ``` ### `Tray` ```js // Deprecated tray.setHighlightMode(true) // Replace with tray.setHighlightMode('on') // Deprecated tray.setHighlightMode(false) // Replace with tray.setHighlightMode('off') ``` ### `webContents` ```js // Deprecated webContents.openDevTools({ detach: true }) // Replace with webContents.openDevTools({ mode: 'detach' }) // Removed webContents.setSize(options) // There is no replacement for this API ``` ### `webFrame` ```js // Deprecated webFrame.registerURLSchemeAsSecure('app') // Replace with protocol.registerStandardSchemes(['app'], { secure: true }) // Deprecated webFrame.registerURLSchemeAsPrivileged('app', { secure: true }) // Replace with protocol.registerStandardSchemes(['app'], { secure: true }) ``` ### `` ```js // Removed webview.setAttribute('disableguestresize', '') // There is no replacement for this API // Removed webview.setAttribute('guestinstance', instanceId) // There is no replacement for this API // Keyboard listeners no longer work on webview tag webview.onkeydown = () => { /* handler */ } webview.onkeyup = () => { /* handler */ } ``` ### Node Headers URL This is the URL specified as `disturl` in a `.npmrc` file or as the `--dist-url` command line flag when building native Node modules. Deprecated: https://atom.io/download/atom-shell Replace with: https://atom.io/download/electron ## Breaking API Changes (2.0) The following list includes the breaking API changes made in Electron 2.0. ### `BrowserWindow` ```js // Deprecated let optionsA = { titleBarStyle: 'hidden-inset' } let windowA = new BrowserWindow(optionsA) // Replace with let optionsB = { titleBarStyle: 'hiddenInset' } let windowB = new BrowserWindow(optionsB) ``` ### `menu` ```js // Removed menu.popup(browserWindow, 100, 200, 2) // Replaced with menu.popup(browserWindow, { x: 100, y: 200, positioningItem: 2 }) ``` ### `nativeImage` ```js // Removed nativeImage.toPng() // Replaced with nativeImage.toPNG() // Removed nativeImage.toJpeg() // Replaced with nativeImage.toJPEG() ``` ### `process` * `process.versions.electron` and `process.version.chrome` will be made read-only properties for consistency with the other `process.versions` properties set by Node. ### `webContents` ```js // Removed webContents.setZoomLevelLimits(1, 2) // Replaced with webContents.setVisualZoomLevelLimits(1, 2) ``` ### `webFrame` ```js // Removed webFrame.setZoomLevelLimits(1, 2) // Replaced with webFrame.setVisualZoomLevelLimits(1, 2) ``` ### `` ```js // Removed webview.setZoomLevelLimits(1, 2) // Replaced with webview.setVisualZoomLevelLimits(1, 2) ``` ### Duplicate ARM Assets Each Electron release includes two identical ARM builds with slightly different filenames, like `electron-v1.7.3-linux-arm.zip` and `electron-v1.7.3-linux-armv7l.zip`. The asset with the `v7l` prefix was added to clarify to users which ARM version it supports, and to disambiguate it from future armv6l and arm64 assets that may be produced. The file _without the prefix_ is still being published to avoid breaking any setups that may be consuming it. Starting at 2.0, the unprefixed file will no longer be published. For details, see [6986](https://github.com/electron/electron/pull/6986) and [7189](https://github.com/electron/electron/pull/7189).