# 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()) ``` ## 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 = function (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()) ``` ## 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).