Define keyboard shortcuts.
Accelerators are Strings that can contain multiple modifiers and a single key code, combined by the +
character, and are used to define keyboard shortcuts throughout your application.
Examples:
CommandOrControl+A
CommandOrControl+Shift+Z
Shortcuts are registered with the globalShortcut
module using the register
method, i.e.
const { app, globalShortcut } = require('electron') app.whenReady().then(() => { // Register a 'CommandOrControl+Y' shortcut listener. globalShortcut.register('CommandOrControl+Y', () => { // Do stuff when Y and either Command/Control is pressed. }) })
On Linux and Windows, the Command
key does not have any effect so use CommandOrControl
which represents Command
on macOS and Control
on Linux and Windows to define some accelerators.
Use Alt
instead of Option
. The Option
key only exists on macOS, whereas the Alt
key is available on all platforms.
The Super
key is mapped to the Windows
key on Windows and Linux and Cmd
on macOS.
Command
(or Cmd
for short)Control
(or Ctrl
for short)CommandOrControl
(or CmdOrCtrl
for short)Alt
Option
AltGr
Shift
Super
0
to 9
A
to Z
F1
to F24
~
, !
, @
, #
, $
, etc.Plus
Space
Tab
Capslock
Numlock
Scrolllock
Backspace
Delete
Insert
Return
(or Enter
as alias)Up
, Down
, Left
and Right
Home
and End
PageUp
and PageDown
Escape
(or Esc
for short)VolumeUp
, VolumeDown
and VolumeMute
MediaNextTrack
, MediaPreviousTrack
, MediaStop
and MediaPlayPause
PrintScreen
num0
- num9
numdec
- decimal keynumadd
- numpad +
keynumsub
- numpad -
keynummult
- numpad *
keynumdiv
- numpad ÷
keyMaking accessible applications is important and we're happy to provide functionality to Devtron and Spectron that gives developers the opportunity to make their apps better for everyone.
Accessibility concerns in Electron applications are similar to those of websites because they're both ultimately HTML. With Electron apps, however, you can't use the online resources for accessibility audits because your app doesn't have a URL to point the auditor to.
These features bring those auditing tools to your Electron app. You can choose to add audits to your tests with Spectron or use them within DevTools with Devtron. Read on for a summary of the tools.
In the testing framework Spectron, you can now audit each window and <webview>
tag in your application. For example:
app.client.auditAccessibility().then(function (audit) { if (audit.failed) { console.error(audit.message) } })
You can read more about this feature in Spectron's documentation.
In Devtron, there is an accessibility tab which will allow you to audit a page in your app, sort and filter the results.
Both of these tools are using the Accessibility Developer Tools library built by Google for Chrome. You can learn more about the accessibility audit rules this library uses on that repository's wiki.
If you know of other great accessibility tools for Electron, add them to the accessibility documentation with a pull request.
Electron applications will automatically enable accessibility features in the presence of assistive technology (e.g. JAWS on Windows or VoiceOver on macOS). See Chrome's accessibility documentation for more details.
You can also manually toggle these features either within your Electron application or by setting flags in third-party native software.
By using the app.setAccessibilitySupportEnabled(enabled)
API, you can manually expose Chrome's accessibility tree to users in the application preferences. Note that the user's system assistive utilities have priority over this setting and will override it.
On macOS, third-party assistive technology can toggle accessibility features inside Electron applications by setting the AXManualAccessibility
attribute programmatically:
CFStringRef kAXManualAccessibility = CFSTR("AXManualAccessibility"); + (void)enableAccessibility:(BOOL)enable inElectronApplication:(NSRunningApplication *)app { AXUIElementRef appRef = AXUIElementCreateApplication(app.processIdentifier); if (appRef == nil) return; CFBooleanRef value = enable ? kCFBooleanTrue : kCFBooleanFalse; AXUIElementSetAttributeValue(appRef, kAXManualAccessibility, value); CFRelease(appRef); }
Control your application's event lifecycle.
Process: Main
The following example shows how to quit the application when the last window is closed:
const { app } = require('electron') app.on('window-all-closed', () => { app.quit() })
The app
object emits the following events:
Emitted when the application has finished basic startup. On Windows and Linux, the will-finish-launching
event is the same as the ready
event; on macOS, this event represents the applicationWillFinishLaunching
notification of NSApplication
. You would usually set up listeners for the open-file
and open-url
events here, and start the crash reporter and auto updater.
In most cases, you should do everything in the ready
event handler.
Returns:
event
EventlaunchInfo
Record<string, any> macOS
Emitted once, when Electron has finished initializing. On macOS, launchInfo
holds the userInfo
of the NSUserNotification
that was used to open the application, if it was launched from Notification Center. You can also call app.isReady()
to check if this event has already fired and app.whenReady()
to get a Promise that is fulfilled when Electron is initialized.
Emitted when all windows have been closed.
If you do not subscribe to this event and all windows are closed, the default behavior is to quit the app; however, if you subscribe, you control whether the app quits or not. If the user pressed Cmd + Q
, or the developer called app.quit()
, Electron will first try to close all the windows and then emit the will-quit
event, and in this case the window-all-closed
event would not be emitted.
Returns:
event
EventEmitted before the application starts closing its windows. Calling event.preventDefault()
will prevent the default behavior, which is terminating the application.
Note: If application quit was initiated by autoUpdater.quitAndInstall()
, then before-quit
is emitted after emitting close
event on all windows and closing them.
Note: On Windows, this event will not be emitted if the app is closed due to a shutdown/restart of the system or a user logout.
Returns:
event
EventEmitted when all windows have been closed and the application will quit. Calling event.preventDefault()
will prevent the default behavior, which is terminating the application.
See the description of the window-all-closed
event for the differences between the will-quit
and window-all-closed
events.
Note: On Windows, this event will not be emitted if the app is closed due to a shutdown/restart of the system or a user logout.
Returns:
event
EventexitCode
IntegerEmitted when the application is quitting.
Note: On Windows, this event will not be emitted if the app is closed due to a shutdown/restart of the system or a user logout.
Returns:
event
Eventpath
StringEmitted when the user wants to open a file with the application. The open-file
event is usually emitted when the application is already open and the OS wants to reuse the application to open the file. open-file
is also emitted when a file is dropped onto the dock and the application is not yet running. Make sure to listen for the open-file
event very early in your application startup to handle this case (even before the ready
event is emitted).
You should call event.preventDefault()
if you want to handle this event.
On Windows, you have to parse process.argv
(in the main process) to get the filepath.
Returns:
event
Eventurl
StringEmitted when the user wants to open a URL with the application. Your application's Info.plist
file must define the URL scheme within the CFBundleURLTypes
key, and set NSPrincipalClass
to AtomApplication
.
You should call event.preventDefault()
if you want to handle this event.
Returns:
event
EventhasVisibleWindows
BooleanEmitted when the application is activated. Various actions can trigger this event, such as launching the application for the first time, attempting to re-launch the application when it's already running, or clicking on the application's dock or taskbar icon.
Returns:
event
EventEmitted when mac application become active. Difference from activate
event is that did-become-active
is emitted every time the app becomes active, not only when Dock icon is clicked or application is re-launched.
Returns:
event
Eventtype
String - A string identifying the activity. Maps to NSUserActivity.activityType
.userInfo
unknown - Contains app-specific state stored by the activity on another device.Emitted during Handoff when an activity from a different device wants to be resumed. You should call event.preventDefault()
if you want to handle this event.
A user activity can be continued only in an app that has the same developer Team ID as the activity's source app and that supports the activity's type. Supported activity types are specified in the app's Info.plist
under the NSUserActivityTypes
key.
Returns:
event
Eventtype
String - A string identifying the activity. Maps to NSUserActivity.activityType
.Emitted during Handoff before an activity from a different device wants to be resumed. You should call event.preventDefault()
if you want to handle this event.
Returns:
event
Eventtype
String - A string identifying the activity. Maps to NSUserActivity.activityType
.error
String - A string with the error's localized description.Emitted during Handoff when an activity from a different device fails to be resumed.
Returns:
event
Eventtype
String - A string identifying the activity. Maps to NSUserActivity.activityType
.userInfo
unknown - Contains app-specific state stored by the activity.Emitted during Handoff after an activity from this device was successfully resumed on another one.
Returns:
event
Eventtype
String - A string identifying the activity. Maps to NSUserActivity.activityType
.userInfo
unknown - Contains app-specific state stored by the activity.Emitted when Handoff is about to be resumed on another device. If you need to update the state to be transferred, you should call event.preventDefault()
immediately, construct a new userInfo
dictionary and call app.updateCurrentActivity()
in a timely manner. Otherwise, the operation will fail and continue-activity-error
will be called.
Returns:
event
EventEmitted when the user clicks the native macOS new tab button. The new tab button is only visible if the current BrowserWindow
has a tabbingIdentifier
Returns:
event
Eventwindow
BrowserWindow
Emitted when a browserWindow gets blurred.
Returns:
event
Eventwindow
BrowserWindow
Emitted when a browserWindow gets focused.
Returns:
event
Eventwindow
BrowserWindow
Emitted when a new browserWindow is created.
Returns:
event
EventwebContents
WebContents
Emitted when a new webContents is created.
Returns:
event
EventwebContents
WebContents
url
Stringerror
String - The error codecertificate
Certificate
callback
FunctionisTrusted
Boolean - Whether to consider the certificate as trustedEmitted when failed to verify the certificate
for url
, to trust the certificate you should prevent the default behavior with event.preventDefault()
and call callback(true)
.
const { app } = require('electron') app.on('certificate-error', (event, webContents, url, error, certificate, callback) => { if (url === 'https://github.com') { // Verification logic. event.preventDefault() callback(true) } else { callback(false) } })
Returns:
event
EventwebContents
WebContents
url
URLcertificateList
Certificate[]
callback
Functioncertificate
Certificate (optional)Emitted when a client certificate is requested.
The url
corresponds to the navigation entry requesting the client certificate and callback
can be called with an entry filtered from the list. Using event.preventDefault()
prevents the application from using the first certificate from the store.
const { app } = require('electron') app.on('select-client-certificate', (event, webContents, url, list, callback) => { event.preventDefault() callback(list[0]) })
Returns:
event
EventwebContents
WebContents
authenticationResponseDetails
Objecturl
URLauthInfo
ObjectisProxy
Booleanscheme
Stringhost
Stringport
Integerrealm
Stringcallback
Functionusername
String (optional)password
String (optional)Emitted when webContents
wants to do basic auth.
The default behavior is to cancel all authentications. To override this you should prevent the default behavior with event.preventDefault()
and call callback(username, password)
with the credentials.
const { app } = require('electron') app.on('login', (event, webContents, details, authInfo, callback) => { event.preventDefault() callback('username', 'secret') })
If callback
is called without a username or password, the authentication request will be cancelled and the authentication error will be returned to the page.
Emitted whenever there is a GPU info update.
Returns:
event
Eventkilled
BooleanEmitted when the GPU process crashes or is killed.
Deprecated: This event is superceded by the child-process-gone
event which contains more information about why the child process disappeared. It isn't always because it crashed. The killed
boolean can be replaced by checking reason === 'killed'
when you switch to that event.
Returns:
event
EventwebContents
WebContents
killed
BooleanEmitted when the renderer process of webContents
crashes or is killed.
Deprecated: This event is superceded by the render-process-gone
event which contains more information about why the render process disappeared. It isn't always because it crashed. The killed
boolean can be replaced by checking reason === 'killed'
when you switch to that event.
Returns:
event
EventwebContents
WebContents
details
Objectreason
String - The reason the render process is gone. Possible values:clean-exit
- Process exited with an exit code of zeroabnormal-exit
- Process exited with a non-zero exit codekilled
- Process was sent a SIGTERM or otherwise killed externallycrashed
- Process crashedoom
- Process ran out of memorylaunch-failed
- Process never successfully launchedintegrity-failure
- Windows code integrity checks failedEmitted when the renderer process unexpectedly disappears. This is normally because it was crashed or killed.
Returns:
event
Eventdetails
Objecttype
String - Process type. One of the following values:Utility
Zygote
Sandbox helper
GPU
Pepper Plugin
Pepper Plugin Broker
Unknown
reason
String - The reason the child process is gone. Possible values:clean-exit
- Process exited with an exit code of zeroabnormal-exit
- Process exited with a non-zero exit codekilled
- Process was sent a SIGTERM or otherwise killed externallycrashed
- Process crashedoom
- Process ran out of memorylaunch-failed
- Process never successfully launchedintegrity-failure
- Windows code integrity checks failedexitCode
Number - The exit code for the process (e.g. status from waitpid if on posix, from GetExitCodeProcess on Windows).name
String (optional) - The name of the process. i.e. for plugins it might be Flash. Examples for utility: Audio Service
, Content Decryption Module Service
, Network Service
, Video Capture
, etc.Emitted when the child process unexpectedly disappears. This is normally because it was crashed or killed. It does not include renderer processes.
Returns:
event
EventaccessibilitySupportEnabled
Boolean - true
when Chrome's accessibility support is enabled, false
otherwise.Emitted when Chrome's accessibility support changes. This event fires when assistive technologies, such as screen readers, are enabled or disabled. See https://www.chromium.org/developers/design-documents/accessibility for more details.
Returns:
session
Session
Emitted when Electron has created a new session
.
const { app } = require('electron') app.on('session-created', (session) => { console.log(session) })
Returns:
event
Eventargv
String[] - An array of the second instance's command line argumentsworkingDirectory
String - The second instance's working directoryThis event will be emitted inside the primary instance of your application when a second instance has been executed and calls app.requestSingleInstanceLock()
.
argv
is an Array of the second instance's command line arguments, and workingDirectory
is its current working directory. Usually applications respond to this by making their primary window focused and non-minimized.
Note: If the second instance is started by a different user than the first, the argv
array will not include the arguments.
This event is guaranteed to be emitted after the ready
event of app
gets emitted.
Note: Extra command line arguments might be added by Chromium, such as --original-process-start-time
.
Returns:
event
EventwebContents
WebContents
Emitted when desktopCapturer.getSources()
is called in the renderer process of webContents
. Calling event.preventDefault()
will make it return empty sources.
Returns:
event
EventwebContents
WebContents
moduleName
StringEmitted when remote.require()
is called in the renderer process of webContents
. Calling event.preventDefault()
will prevent the module from being returned. Custom value can be returned by setting event.returnValue
.
Returns:
event
EventwebContents
WebContents
globalName
StringEmitted when remote.getGlobal()
is called in the renderer process of webContents
. Calling event.preventDefault()
will prevent the global from being returned. Custom value can be returned by setting event.returnValue
.
Returns:
event
EventwebContents
WebContents
moduleName
StringEmitted when remote.getBuiltin()
is called in the renderer process of webContents
. Calling event.preventDefault()
will prevent the module from being returned. Custom value can be returned by setting event.returnValue
.
Returns:
event
EventwebContents
WebContents
Emitted when remote.getCurrentWindow()
is called in the renderer process of webContents
. Calling event.preventDefault()
will prevent the object from being returned. Custom value can be returned by setting event.returnValue
.
Returns:
event
EventwebContents
WebContents
Emitted when remote.getCurrentWebContents()
is called in the renderer process of webContents
. Calling event.preventDefault()
will prevent the object from being returned. Custom value can be returned by setting event.returnValue
.
The app
object has the following methods:
Note: Some methods are only available on specific operating systems and are labeled as such.
app.quit()
Try to close all windows. The before-quit
event will be emitted first. If all windows are successfully closed, the will-quit
event will be emitted and by default the application will terminate.
This method guarantees that all beforeunload
and unload
event handlers are correctly executed. It is possible that a window cancels the quitting by returning false
in the beforeunload
event handler.
app.exit([exitCode])
exitCode
Integer (optional)Exits immediately with exitCode
. exitCode
defaults to 0.
All windows will be closed immediately without asking the user, and the before-quit
and will-quit
events will not be emitted.
app.relaunch([options])
options
Object (optional)args
String[] (optional)execPath
String (optional)Relaunches the app when current instance exits.
By default, the new instance will use the same working directory and command line arguments with current instance. When args
is specified, the args
will be passed as command line arguments instead. When execPath
is specified, the execPath
will be executed for relaunch instead of current app.
Note that this method does not quit the app when executed, you have to call app.quit
or app.exit
after calling app.relaunch
to make the app restart.
When app.relaunch
is called for multiple times, multiple instances will be started after current instance exited.
An example of restarting current instance immediately and adding a new command line argument to the new instance:
const { app } = require('electron') app.relaunch({ args: process.argv.slice(1).concat(['--relaunch']) }) app.exit(0)
app.isReady()
Returns Boolean
- true
if Electron has finished initializing, false
otherwise. See also app.whenReady()
.
app.whenReady()
Returns Promise<void>
- fulfilled when Electron is initialized. May be used as a convenient alternative to checking app.isReady()
and subscribing to the ready
event if the app is not ready yet.
app.focus([options])
options
Object (optional)steal
Boolean macOS - Make the receiver the active app even if another app is currently active.On Linux, focuses on the first visible window. On macOS, makes the application the active app. On Windows, focuses on the application's first window.
You should seek to use the steal
option as sparingly as possible.
app.hide()
macOS
Hides all application windows without minimizing them.
app.show()
macOS
Shows application windows after they were hidden. Does not automatically focus them.
app.setAppLogsPath([path])
path
String (optional) - A custom path for your logs. Must be absolute.Sets or creates a directory your app's logs which can then be manipulated with app.getPath()
or app.setPath(pathName, newPath)
.
Calling app.setAppLogsPath()
without a path
parameter will result in this directory being set to ~/Library/Logs/YourAppName
on macOS, and inside the userData
directory on Linux and Windows.
app.getAppPath()
Returns String
- The current application directory.
app.getPath(name)
name
String - You can request the following paths by the name:home
User's home directory.appData
Per-user application data directory, which by default points to:%APPDATA%
on Windows$XDG_CONFIG_HOME
or ~/.config
on Linux~/Library/Application Support
on macOSuserData
The directory for storing your app's configuration files, which by default it is the appData
directory appended with your app's name.cache
temp
Temporary directory.exe
The current executable file.module
The libchromiumcontent
library.desktop
The current user's Desktop directory.documents
Directory for a user's "My Documents".downloads
Directory for a user's downloads.music
Directory for a user's music.pictures
Directory for a user's pictures.videos
Directory for a user's videos.recent
Directory for the user's recent files (Windows only).logs
Directory for your app's log folder.pepperFlashSystemPlugin
Full path to the system version of the Pepper Flash plugin.crashDumps
Directory where crash dumps are stored.Returns String
- A path to a special directory or file associated with name
. On failure, an Error
is thrown.
If app.getPath('logs')
is called without called app.setAppLogsPath()
being called first, a default log directory will be created equivalent to calling app.setAppLogsPath()
without a path
parameter.
app.getFileIcon(path[, options])
path
Stringoptions
Object (optional)size
Stringsmall
- 16x16normal
- 32x32large
- 48x48 on Linux, 32x32 on Windows, unsupported on macOS.Returns Promise<NativeImage>
- fulfilled with the app's icon, which is a NativeImage.
Fetches a path's associated icon.
On Windows, there a 2 kinds of icons:
.mp3
, .png
, etc..exe
, .dll
, .ico
.On Linux and macOS, icons depend on the application associated with file mime type.
app.setPath(name, path)
name
Stringpath
StringOverrides the path
to a special directory or file associated with name
. If the path specifies a directory that does not exist, an Error
is thrown. In that case, the directory should be created with fs.mkdirSync
or similar.
You can only override paths of a name
defined in app.getPath
.
By default, web pages' cookies and caches will be stored under the userData
directory. If you want to change this location, you have to override the userData
path before the ready
event of the app
module is emitted.
app.getVersion()
Returns String
- The version of the loaded application. If no version is found in the application's package.json
file, the version of the current bundle or executable is returned.
app.getName()
Returns String
- The current application's name, which is the name in the application's package.json
file.
Usually the name
field of package.json
is a short lowercase name, according to the npm modules spec. You should usually also specify a productName
field, which is your application's full capitalized name, and which will be preferred over name
by Electron.
app.setName(name)
name
StringOverrides the current application's name.
Note: This function overrides the name used internally by Electron; it does not affect the name that the OS uses.
app.getLocale()
Returns String
- The current application locale. Possible return values are documented here.
To set the locale, you'll want to use a command line switch at app startup, which may be found here.
Note: When distributing your packaged app, you have to also ship the locales
folder.
Note: On Windows, you have to call it after the ready
events gets emitted.
app.getLocaleCountryCode()
Returns String
- User operating system's locale two-letter ISO 3166 country code. The value is taken from native OS APIs.
Note: When unable to detect locale country code, it returns empty string.
app.addRecentDocument(path)
macOS Windows
path
StringAdds path
to the recent documents list.
This list is managed by the OS. On Windows, you can visit the list from the task bar, and on macOS, you can visit it from dock menu.
app.clearRecentDocuments()
macOS Windows
Clears the recent documents list.
app.setAsDefaultProtocolClient(protocol[, path, args])
protocol
String - The name of your protocol, without ://
. For example, if you want your app to handle electron://
links, call this method with electron
as the parameter.path
String (optional) Windows - The path to the Electron executable. Defaults to process.execPath
args
String[] (optional) Windows - Arguments passed to the executable. Defaults to an empty arrayReturns Boolean
- Whether the call succeeded.
Sets the current executable as the default handler for a protocol (aka URI scheme). It allows you to integrate your app deeper into the operating system. Once registered, all links with your-protocol://
will be opened with the current executable. The whole link, including protocol, will be passed to your application as a parameter.
Note: On macOS, you can only register protocols that have been added to your app's info.plist
, which cannot be modified at runtime. However, you can change the file during build time via Electron Forge, Electron Packager, or by editing info.plist
with a text editor. Please refer to Apple's documentation for details.
Note: In a Windows Store environment (when packaged as an appx
) this API will return true
for all calls but the registry key it sets won't be accessible by other applications. In order to register your Windows Store application as a default protocol handler you must declare the protocol in your manifest.
The API uses the Windows Registry and LSSetDefaultHandlerForURLScheme
internally.
app.removeAsDefaultProtocolClient(protocol[, path, args])
macOS Windows
protocol
String - The name of your protocol, without ://
.path
String (optional) Windows - Defaults to process.execPath
args
String[] (optional) Windows - Defaults to an empty arrayReturns Boolean
- Whether the call succeeded.
This method checks if the current executable as the default handler for a protocol (aka URI scheme). If so, it will remove the app as the default handler.
app.isDefaultProtocolClient(protocol[, path, args])
protocol
String - The name of your protocol, without ://
.path
String (optional) Windows - Defaults to process.execPath
args
String[] (optional) Windows - Defaults to an empty arrayReturns Boolean
- Whether the current executable is the default handler for a protocol (aka URI scheme).
Note: On macOS, you can use this method to check if the app has been registered as the default protocol handler for a protocol. You can also verify this by checking ~/Library/Preferences/com.apple.LaunchServices.plist
on the macOS machine. Please refer to Apple's documentation for details.
The API uses the Windows Registry and LSCopyDefaultHandlerForURLScheme
internally.
app.getApplicationNameForProtocol(url)
url
String - a URL with the protocol name to check. Unlike the other methods in this family, this accepts an entire URL, including ://
at a minimum (e.g. https://
).Returns String
- Name of the application handling the protocol, or an empty string if there is no handler. For instance, if Electron is the default handler of the URL, this could be Electron
on Windows and Mac. However, don't rely on the precise format which is not guaranteed to remain unchanged. Expect a different format on Linux, possibly with a .desktop
suffix.
This method returns the application name of the default handler for the protocol (aka URI scheme) of a URL.
app.getApplicationInfoForProtocol(url)
macOS Windows
url
String - a URL with the protocol name to check. Unlike the other methods in this family, this accepts an entire URL, including ://
at a minimum (e.g. https://
).Returns Promise<Object>
- Resolve with an object containing the following:
icon
NativeImage - the display icon of the app handling the protocol.path
String - installation path of the app handling the protocol.name
String - display name of the app handling the protocol.This method returns a promise that contains the application name, icon and path of the default handler for the protocol (aka URI scheme) of a URL.
app.setUserTasks(tasks)
Windows
tasks
Task[] - Array of Task
objectsAdds tasks
to the Tasks category of the Jump List on Windows.
tasks
is an array of Task
objects.
Returns Boolean
- Whether the call succeeded.
Note: If you'd like to customize the Jump List even more use app.setJumpList(categories)
instead.
app.getJumpListSettings()
Windows
Returns Object
:
minItems
Integer - The minimum number of items that will be shown in the Jump List (for a more detailed description of this value see the MSDN docs).removedItems
JumpListItem[] - Array of JumpListItem
objects that correspond to items that the user has explicitly removed from custom categories in the Jump List. These items must not be re-added to the Jump List in the next call to app.setJumpList()
, Windows will not display any custom category that contains any of the removed items.app.setJumpList(categories)
Windows
categories
JumpListCategory[] | null
- Array of JumpListCategory
objects.Sets or removes a custom Jump List for the application, and returns one of the following strings:
ok
- Nothing went wrong.error
- One or more errors occurred, enable runtime logging to figure out the likely cause.invalidSeparatorError
- An attempt was made to add a separator to a custom category in the Jump List. Separators are only allowed in the standard Tasks
category.fileTypeRegistrationError
- An attempt was made to add a file link to the Jump List for a file type the app isn't registered to handle.customCategoryAccessDeniedError
- Custom categories can't be added to the Jump List due to user privacy or group policy settings.If categories
is null
the previously set custom Jump List (if any) will be replaced by the standard Jump List for the app (managed by Windows).
Note: If a JumpListCategory
object has neither the type
nor the name
property set then its type
is assumed to be tasks
. If the name
property is set but the type
property is omitted then the type
is assumed to be custom
.
Note: Users can remove items from custom categories, and Windows will not allow a removed item to be added back into a custom category until after the next successful call to app.setJumpList(categories)
. Any attempt to re-add a removed item to a custom category earlier than that will result in the entire custom category being omitted from the Jump List. The list of removed items can be obtained using app.getJumpListSettings()
.
Here's a very simple example of creating a custom Jump List:
const { app } = require('electron') app.setJumpList([ { type: 'custom', name: 'Recent Projects', items: [ { type: 'file', path: 'C:\\Projects\\project1.proj' }, { type: 'file', path: 'C:\\Projects\\project2.proj' } ] }, { // has a name so `type` is assumed to be "custom" name: 'Tools', items: [ { type: 'task', title: 'Tool A', program: process.execPath, args: '--run-tool-a', icon: process.execPath, iconIndex: 0, description: 'Runs Tool A' }, { type: 'task', title: 'Tool B', program: process.execPath, args: '--run-tool-b', icon: process.execPath, iconIndex: 0, description: 'Runs Tool B' } ] }, { type: 'frequent' }, { // has no name and no type so `type` is assumed to be "tasks" items: [ { type: 'task', title: 'New Project', program: process.execPath, args: '--new-project', description: 'Create a new project.' }, { type: 'separator' }, { type: 'task', title: 'Recover Project', program: process.execPath, args: '--recover-project', description: 'Recover Project' } ] } ])
app.requestSingleInstanceLock()
Returns Boolean
The return value of this method indicates whether or not this instance of your application successfully obtained the lock. If it failed to obtain the lock, you can assume that another instance of your application is already running with the lock and exit immediately.
I.e. This method returns true
if your process is the primary instance of your application and your app should continue loading. It returns false
if your process should immediately quit as it has sent its parameters to another instance that has already acquired the lock.
On macOS, the system enforces single instance automatically when users try to open a second instance of your app in Finder, and the open-file
and open-url
events will be emitted for that. However when users start your app in command line, the system's single instance mechanism will be bypassed, and you have to use this method to ensure single instance.
An example of activating the window of primary instance when a second instance starts:
const { app } = require('electron') let myWindow = null const gotTheLock = app.requestSingleInstanceLock() if (!gotTheLock) { app.quit() } else { app.on('second-instance', (event, commandLine, workingDirectory) => { // Someone tried to run a second instance, we should focus our window. if (myWindow) { if (myWindow.isMinimized()) myWindow.restore() myWindow.focus() } }) // Create myWindow, load the rest of the app, etc... app.whenReady().then(() => { myWindow = createWindow() }) }
app.hasSingleInstanceLock()
Returns Boolean
This method returns whether or not this instance of your app is currently holding the single instance lock. You can request the lock with app.requestSingleInstanceLock()
and release with app.releaseSingleInstanceLock()
app.releaseSingleInstanceLock()
Releases all locks that were created by requestSingleInstanceLock
. This will allow multiple instances of the application to once again run side by side.
app.setUserActivity(type, userInfo[, webpageURL])
macOS
type
String - Uniquely identifies the activity. Maps to NSUserActivity.activityType
.userInfo
any - App-specific state to store for use by another device.webpageURL
String (optional) - The webpage to load in a browser if no suitable app is installed on the resuming device. The scheme must be http
or https
.Creates an NSUserActivity
and sets it as the current activity. The activity is eligible for Handoff to another device afterward.
app.getCurrentActivityType()
macOS
Returns String
- The type of the currently running activity.
app.invalidateCurrentActivity()
macOS
Invalidates the current Handoff user activity.
app.resignCurrentActivity()
macOS
Marks the current Handoff user activity as inactive without invalidating it.
app.updateCurrentActivity(type, userInfo)
macOS
type
String - Uniquely identifies the activity. Maps to NSUserActivity.activityType
.userInfo
any - App-specific state to store for use by another device.Updates the current activity if its type matches type
, merging the entries from userInfo
into its current userInfo
dictionary.
app.setAppUserModelId(id)
Windows
id
StringChanges the Application User Model ID to id
.
app.setActivationPolicy(policy)
macOS
policy
String - Can be 'regular', 'accessory', or 'prohibited'.Sets the activation policy for a given app.
Activation policy types:
app.importCertificate(options, callback)
Linux
options
Objectcertificate
String - Path for the pkcs12 file.password
String - Passphrase for the certificate.callback
Functionresult
Integer - Result of import.Imports the certificate in pkcs12 format into the platform certificate store. callback
is called with the result
of import operation, a value of 0
indicates success while any other value indicates failure according to Chromium net_error_list.
app.disableHardwareAcceleration()
Disables hardware acceleration for current app.
This method can only be called before app is ready.
app.disableDomainBlockingFor3DAPIs()
By default, Chromium disables 3D APIs (e.g. WebGL) until restart on a per domain basis if the GPU processes crashes too frequently. This function disables that behavior.
This method can only be called before app is ready.
app.getAppMetrics()
Returns ProcessMetric[]
: Array of ProcessMetric
objects that correspond to memory and CPU usage statistics of all the processes associated with the app.
app.getGPUFeatureStatus()
Returns GPUFeatureStatus
- The Graphics Feature Status from chrome://gpu/
.
Note: This information is only usable after the gpu-info-update
event is emitted.
app.getGPUInfo(infoType)
infoType
String - Can be basic
or complete
.Returns Promise<unknown>
For infoType
equal to complete
: Promise is fulfilled with Object
containing all the GPU Information as in chromium's GPUInfo object. This includes the version and driver information that's shown on chrome://gpu
page.
For infoType
equal to basic
: Promise is fulfilled with Object
containing fewer attributes than when requested with complete
. Here's an example of basic response:
{ auxAttributes: { amdSwitchable: true, canSupportThreadedTextureMailbox: false, directComposition: false, directRendering: true, glResetNotificationStrategy: 0, inProcessGpu: true, initializationTime: 0, jpegDecodeAcceleratorSupported: false, optimus: false, passthroughCmdDecoder: false, sandboxed: false, softwareRendering: false, supportsOverlays: false, videoDecodeAcceleratorFlags: 0 }, gpuDevice: [{ active: true, deviceId: 26657, vendorId: 4098 }, { active: false, deviceId: 3366, vendorId: 32902 }], machineModelName: 'MacBookPro', machineModelVersion: '11.5' }
Using basic
should be preferred if only basic information like vendorId
or driverId
is needed.
app.setBadgeCount(count)
Linux macOS
count
IntegerReturns Boolean
- Whether the call succeeded.
Sets the counter badge for current app. Setting the count to 0
will hide the badge.
On macOS, it shows on the dock icon. On Linux, it only works for Unity launcher.
Note: Unity launcher requires the existence of a .desktop
file to work, for more information please read Desktop Environment Integration.
app.getBadgeCount()
Linux macOS
Returns Integer
- The current value displayed in the counter badge.
app.isUnityRunning()
Linux
Returns Boolean
- Whether the current desktop environment is Unity launcher.
app.getLoginItemSettings([options])
macOS Windows
options
Object (optional)path
String (optional) Windows - The executable path to compare against. Defaults to process.execPath
.args
String[] (optional) Windows - The command-line arguments to compare against. Defaults to an empty array.If you provided path
and args
options to app.setLoginItemSettings
, then you need to pass the same arguments here for openAtLogin
to be set correctly.
Returns Object
:
openAtLogin
Boolean - true
if the app is set to open at login.openAsHidden
Boolean macOS - true
if the app is set to open as hidden at login. This setting is not available on MAS builds.wasOpenedAtLogin
Boolean macOS - true
if the app was opened at login automatically. This setting is not available on MAS builds.wasOpenedAsHidden
Boolean macOS - true
if the app was opened as a hidden login item. This indicates that the app should not open any windows at startup. This setting is not available on MAS builds.restoreState
Boolean macOS - true
if the app was opened as a login item that should restore the state from the previous session. This indicates that the app should restore the windows that were open the last time the app was closed. This setting is not available on MAS builds.executableWillLaunchAtLogin
Boolean Windows - true
if app is set to open at login and its run key is not deactivated. This differs from openAtLogin
as it ignores the args
option, this property will be true if the given executable would be launched at login with any arguments.launchItems
Object[] Windowsname
String Windows - name value of a registry entry.path
String Windows - The executable to an app that corresponds to a registry entry.args
String[] Windows - the command-line arguments to pass to the executable.scope
String Windows - one of user
or machine
. Indicates whether the registry entry is under HKEY_CURRENT USER
or HKEY_LOCAL_MACHINE
.enabled
Boolean Windows - true
if the app registry key is startup approved and therefore shows as enabled
in Task Manager and Windows settings.app.setLoginItemSettings(settings)
macOS Windows
settings
ObjectopenAtLogin
Boolean (optional) - true
to open the app at login, false
to remove the app as a login item. Defaults to false
.openAsHidden
Boolean (optional) macOS - true
to open the app as hidden. Defaults to false
. The user can edit this setting from the System Preferences so app.getLoginItemSettings().wasOpenedAsHidden
should be checked when the app is opened to know the current value. This setting is not available on MAS builds.path
String (optional) Windows - The executable to launch at login. Defaults to process.execPath
.args
String[] (optional) Windows - The command-line arguments to pass to the executable. Defaults to an empty array. Take care to wrap paths in quotes.enabled
Boolean (optional) Windows - true
will change the startup approved registry key and enable / disable
the App in Task Manager and Windows Settings. Defaults to true
.name
String (optional) Windows - value name to write into registry. Defaults to the app's AppUserModelId(). Set the app's login item settings.To work with Electron's autoUpdater
on Windows, which uses Squirrel, you'll want to set the launch path to Update.exe, and pass arguments that specify your application name. For example:
const appFolder = path.dirname(process.execPath) const updateExe = path.resolve(appFolder, '..', 'Update.exe') const exeName = path.basename(process.execPath) app.setLoginItemSettings({ openAtLogin: true, path: updateExe, args: [ '--processStart', `"${exeName}"`, '--process-start-args', `"--hidden"` ] })
app.isAccessibilitySupportEnabled()
macOS Windows
Returns Boolean
- true
if Chrome's accessibility support is enabled, false
otherwise. This API will return true
if the use of assistive technologies, such as screen readers, has been detected. See https://www.chromium.org/developers/design-documents/accessibility for more details.
app.setAccessibilitySupportEnabled(enabled)
macOS Windows
enabled
Boolean - Enable or disable accessibility tree renderingManually enables Chrome's accessibility support, allowing to expose accessibility switch to users in application settings. See Chromium's accessibility docs for more details. Disabled by default.
This API must be called after the ready
event is emitted.
Note: Rendering accessibility tree can significantly affect the performance of your app. It should not be enabled by default.
app.showAboutPanel()
Show the app's about panel options. These options can be overridden with app.setAboutPanelOptions(options)
.
app.setAboutPanelOptions(options)
options
ObjectapplicationName
String (optional) - The app's name.applicationVersion
String (optional) - The app's version.copyright
String (optional) - Copyright information.version
String (optional) macOS - The app's build version number.credits
String (optional) macOS Windows - Credit information.authors
String[] (optional) Linux - List of app authors.website
String (optional) Linux - The app's website.iconPath
String (optional) Linux Windows - Path to the app's icon in a JPEG or PNG file format. On Linux, will be shown as 64x64 pixels while retaining aspect ratio.Set the about panel options. This will override the values defined in the app's .plist
file on macOS. See the Apple docs for more details. On Linux, values must be set in order to be shown; there are no defaults.
If you do not set credits
but still wish to surface them in your app, AppKit will look for a file named "Credits.html", "Credits.rtf", and "Credits.rtfd", in that order, in the bundle returned by the NSBundle class method main. The first file found is used, and if none is found, the info area is left blank. See Apple documentation for more information.
app.isEmojiPanelSupported()
Returns Boolean
- whether or not the current OS version allows for native emoji pickers.
app.showEmojiPanel()
macOS Windows
Show the platform's native emoji picker.
app.startAccessingSecurityScopedResource(bookmarkData)
mas
bookmarkData
String - The base64 encoded security scoped bookmark data returned by the dialog.showOpenDialog
or dialog.showSaveDialog
methods.Returns Function
- This function must be called once you have finished accessing the security scoped file. If you do not remember to stop accessing the bookmark, kernel resources will be leaked and your app will lose its ability to reach outside the sandbox completely, until your app is restarted.
// Start accessing the file. const stopAccessingSecurityScopedResource = app.startAccessingSecurityScopedResource(data) // You can now access the file outside of the sandbox 🎉 // Remember to stop accessing the file once you've finished with it. stopAccessingSecurityScopedResource()
Start accessing a security scoped resource. With this method Electron applications that are packaged for the Mac App Store may reach outside their sandbox to access files chosen by the user. See Apple's documentation for a description of how this system works.
app.enableSandbox()
Enables full sandbox mode on the app. This means that all renderers will be launched sandboxed, regardless of the value of the sandbox
flag in WebPreferences.
This method can only be called before app is ready.
app.isInApplicationsFolder()
macOS
Returns Boolean
- Whether the application is currently running from the systems Application folder. Use in combination with app.moveToApplicationsFolder()
app.moveToApplicationsFolder([options])
macOS
options
Object (optional)conflictHandler
Function\conflictType
String - The type of move conflict encountered by the handler; can be exists
or existsAndRunning
, where exists
means that an app of the same name is present in the Applications directory and existsAndRunning
means both that it exists and that it's presently running.Returns Boolean
- Whether the move was successful. Please note that if the move is successful, your application will quit and relaunch.
No confirmation dialog will be presented by default. If you wish to allow the user to confirm the operation, you may do so using the dialog
API.
NOTE: This method throws errors if anything other than the user causes the move to fail. For instance if the user cancels the authorization dialog, this method returns false. If we fail to perform the copy, then this method will throw an error. The message in the error should be informative and tell you exactly what went wrong.
By default, if an app of the same name as the one being moved exists in the Applications directory and is not running, the existing app will be trashed and the active app moved into its place. If it is running, the pre-existing running app will assume focus and the previously active app will quit itself. This behavior can be changed by providing the optional conflict handler, where the boolean returned by the handler determines whether or not the move conflict is resolved with default behavior. i.e. returning false
will ensure no further action is taken, returning true
will result in the default behavior and the method continuing.
For example:
app.moveToApplicationsFolder({ conflictHandler: (conflictType) => { if (conflictType === 'exists') { return dialog.showMessageBoxSync({ type: 'question', buttons: ['Halt Move', 'Continue Move'], defaultId: 0, message: 'An app of this name already exists' }) === 1 } } })
Would mean that if an app already exists in the user directory, if the user chooses to 'Continue Move' then the function would continue with its default behavior and the existing app will be trashed and the active app moved into its place.
app.isSecureKeyboardEntryEnabled()
macOS
Returns Boolean
- whether Secure Keyboard Entry
is enabled.
By default this API will return false
.
app.setSecureKeyboardEntryEnabled(enabled)
macOS
enabled
Boolean - Enable or disable Secure Keyboard Entry
Set the Secure Keyboard Entry
is enabled in your application.
By using this API, important information such as password and other sensitive information can be prevented from being intercepted by other processes.
See Apple's documentation for more details.
Note: Enable Secure Keyboard Entry
only when it is needed and disable it when it is no longer needed.
app.accessibilitySupportEnabled
macOS Windows
A Boolean
property that's true
if Chrome's accessibility support is enabled, false
otherwise. This property will be true
if the use of assistive technologies, such as screen readers, has been detected. Setting this property to true
manually enables Chrome's accessibility support, allowing developers to expose accessibility switch to users in application settings.
See Chromium's accessibility docs for more details. Disabled by default.
This API must be called after the ready
event is emitted.
Note: Rendering accessibility tree can significantly affect the performance of your app. It should not be enabled by default.
app.applicationMenu
A Menu | null
property that returns Menu
if one has been set and null
otherwise. Users can pass a Menu to set this property.
app.badgeCount
Linux macOS
An Integer
property that returns the badge count for current app. Setting the count to 0
will hide the badge.
On macOS, setting this with any nonzero integer shows on the dock icon. On Linux, this property only works for Unity launcher.
Note: Unity launcher requires the existence of a .desktop
file to work, for more information please read Desktop Environment Integration.
Note: On macOS, you need to ensure that your application has the permission to display notifications for this property to take effect.
app.commandLine
Readonly
A CommandLine
object that allows you to read and manipulate the command line arguments that Chromium uses.
app.dock
macOS Readonly
A Dock
| undefined
object that allows you to perform actions on your app icon in the user's dock on macOS.
app.isPackaged
Readonly
A Boolean
property that returns true
if the app is packaged, false
otherwise. For many apps, this property can be used to distinguish development and production environments.
app.name
A String
property that indicates the current application's name, which is the name in the application's package.json
file.
Usually the name
field of package.json
is a short lowercase name, according to the npm modules spec. You should usually also specify a productName
field, which is your application's full capitalized name, and which will be preferred over name
by Electron.
app.userAgentFallback
A String
which is the user agent string Electron will use as a global fallback.
This is the user agent that will be used when no user agent is set at the webContents
or session
level. It is useful for ensuring that your entire app has the same user agent. Set to a custom value as early as possible in your app's initialization to ensure that your overridden value is used.
app.allowRendererProcessReuse
A Boolean
which when true
disables the overrides that Electron has in place to ensure renderer processes are restarted on every navigation. The current default value for this property is true
.
The intention is for these overrides to become disabled by default and then at some point in the future this property will be removed. This property impacts which native modules you can use in the renderer process. For more information on the direction Electron is going with renderer process restarts and usage of native modules in the renderer process please check out this Tracking Issue.
app.runningUnderRosettaTranslation
macOS Readonly
A Boolean
which when true
indicates that the app is currently running under the Rosetta Translator Environment.
You can use this property to prompt users to download the arm64 version of your application when they are running the x64 version under Rosetta incorrectly.
Whenever your Electron application is not behaving the way you wanted it to, an array of debugging tools might help you find coding errors, performance bottlenecks, or optimization opportunities.
The most comprehensive tool to debug individual renderer processes is the Chromium Developer Toolset. It is available for all renderer processes, including instances of BrowserWindow
, BrowserView
, and WebView
. You can open them programmatically by calling the openDevTools()
API on the webContents
of the instance:
const { BrowserWindow } = require('electron') const win = new BrowserWindow() win.webContents.openDevTools()
Google offers excellent documentation for their developer tools. We recommend that you make yourself familiar with them - they are usually one of the most powerful utilities in any Electron Developer's tool belt.
Debugging the main process is a bit trickier, since you cannot open developer tools for them. The Chromium Developer Tools can be used to debug Electron's main process thanks to a closer collaboration between Google / Chrome and Node.js, but you might encounter oddities like require
not being present in the console.
For more information, see the Debugging the Main Process documentation.
If the V8 context crashes, the DevTools will display this message.
DevTools was disconnected from the page. Once page is reloaded, DevTools will automatically reconnect.
Chromium logs can be enabled via the ELECTRON_ENABLE_LOGGING
environment variable. For more information, see the environment variables documentation.
Alternatively, the command line argument --enable-logging
can be passed. More information is available in the command line switches documentation.
To distribute your app with Electron, you need to package and rebrand it. The easiest way to do this is to use one of the following third party packaging tools:
These tools will take care of all the steps you need to take to end up with a distributable Electron applications, such as packaging your application, rebranding the executable, setting the right icons and optionally creating installers.
You can also choose to manually get your app ready for distribution. The steps needed to do this are outlined below.
To distribute your app with Electron, you need to download Electron's prebuilt binaries. Next, the folder containing your app should be named app
and placed in Electron's resources directory as shown in the following examples. Note that the location of Electron's prebuilt binaries is indicated with electron/
in the examples below.
On macOS:
electron/Electron.app/Contents/Resources/app/ ├── package.json ├── main.js └── index.html
On Windows and Linux:
electron/resources/app ├── package.json ├── main.js └── index.html
Then execute Electron.app
(or electron
on Linux, electron.exe
on Windows), and Electron will start as your app. The electron
directory will then be your distribution to deliver to final users.
Apart from shipping your app by copying all of its source files, you can also package your app into an asar archive to avoid exposing your app's source code to users.
To use an asar
archive to replace the app
folder, you need to rename the archive to app.asar
, and put it under Electron's resources directory like below, and Electron will then try to read the archive and start from it.
On macOS:
electron/Electron.app/Contents/Resources/ └── app.asar
On Windows and Linux:
electron/resources/ └── app.asar
More details can be found in Application packaging.
After bundling your app into Electron, you will want to rebrand Electron before distributing it to users.
You can rename electron.exe
to any name you like, and edit its icon and other information with tools like rcedit.
You can rename Electron.app
to any name you want, and you also have to rename the CFBundleDisplayName
, CFBundleIdentifier
and CFBundleName
fields in the following files:
Electron.app/Contents/Info.plist
Electron.app/Contents/Frameworks/Electron Helper.app/Contents/Info.plist
You can also rename the helper app to avoid showing Electron Helper
in the Activity Monitor, but make sure you have renamed the helper app's executable file's name.
The structure of a renamed app would be like:
MyApp.app/Contents ├── Info.plist ├── MacOS/ │ └── MyApp └── Frameworks/ └── MyApp Helper.app ├── Info.plist └── MacOS/ └── MyApp Helper
You can rename the electron
executable to any name you like.
It is also possible to rebrand Electron by changing the product name and building it from source. To do this you need to set the build argument corresponding to the product name (electron_product_name = "YourProductName"
) in the args.gn
file and rebuild.
Creating a custom fork of Electron is almost certainly not something you will need to do in order to build your app, even for "Production Level" applications. Using a tool such as electron-packager
or electron-forge
will allow you to "Rebrand" Electron without having to do these steps.
You need to fork Electron when you have custom C++ code that you have patched directly into Electron, that either cannot be upstreamed, or has been rejected from the official version. As maintainers of Electron, we very much would like to make your scenario work, so please try as hard as you can to get your changes into the official version of Electron, it will be much much easier on you, and we appreciate your help.
Install Surf, via npm: npm install -g [email protected]
Create a new S3 bucket and create the following empty directory structure:
- electron/ - symbols/ - dist/
Set the following Environment Variables:
ELECTRON_GITHUB_TOKEN
- a token that can create releases on GitHubELECTRON_S3_ACCESS_KEY
, ELECTRON_S3_BUCKET
, ELECTRON_S3_SECRET_KEY
- the place where you'll upload Node.js headers as well as symbolsELECTRON_RELEASE
- Set to true
and the upload part will run, leave unset and surf-build
will do CI-type checks, appropriate to run for every pull request.CI
- Set to true
or else it will failGITHUB_TOKEN
- set it to the same as ELECTRON_GITHUB_TOKEN
SURF_TEMP
- set to C:\Temp
on Windows to prevent path too long issuesTARGET_ARCH
- set to ia32
or x64
In script/upload.py
, you must set ELECTRON_REPO
to your fork (MYORG/electron
), especially if you are a contributor to Electron proper.
surf-build -r https://github.com/MYORG/electron -s YOUR_COMMIT -n 'surf-PLATFORM-ARCH'
Wait a very, very long time for the build to complete.
To mitigate issues around long path names on Windows, slightly speed up require
and conceal your source code from cursory inspection, you can choose to package your app into an asar archive with little changes to your source code.
Most users will get this feature for free, since it's supported out of the box by electron-packager
, electron-forge
, and electron-builder
. If you are not using any of these tools, read on.
asar
ArchivesAn asar archive is a simple tar-like format that concatenates files into a single file. Electron can read arbitrary files from it without unpacking the whole file.
Steps to package your app into an asar
archive:
$ npm install -g asar
asar pack
$ asar pack your-app app.asar
asar
ArchivesIn Electron there are two sets of APIs: Node APIs provided by Node.js and Web APIs provided by Chromium. Both APIs support reading files from asar
archives.
With special patches in Electron, Node APIs like fs.readFile
and require
treat asar
archives as virtual directories, and the files in it as normal files in the filesystem.
For example, suppose we have an example.asar
archive under /path/to
:
$ asar list /path/to/example.asar /app.js /file.txt /dir/module.js /static/index.html /static/main.css /static/jquery.min.js
Read a file in the asar
archive:
const fs = require('fs') fs.readFileSync('/path/to/example.asar/file.txt')
List all files under the root of the archive:
const fs = require('fs') fs.readdirSync('/path/to/example.asar')
Use a module from the archive:
require('./path/to/example.asar/dir/module.js')
You can also display a web page in an asar
archive with BrowserWindow
:
const { BrowserWindow } = require('electron') const win = new BrowserWindow() win.loadURL('file:///path/to/example.asar/static/index.html')
In a web page, files in an archive can be requested with the file:
protocol. Like the Node API, asar
archives are treated as directories.
For example, to get a file with $.get
:
<script> let $ = require('./jquery.min.js') $.get('file:///path/to/example.asar/file.txt', (data) => { console.log(data) }) </script>
asar
Archive as a Normal FileFor some cases like verifying the asar
archive's checksum, we need to read the content of an asar
archive as a file. For this purpose you can use the built-in original-fs
module which provides original fs
APIs without asar
support:
const originalFs = require('original-fs') originalFs.readFileSync('/path/to/example.asar')
You can also set process.noAsar
to true
to disable the support for asar
in the fs
module:
const fs = require('fs') process.noAsar = true fs.readFileSync('/path/to/example.asar')
Even though we tried hard to make asar
archives in the Node API work like directories as much as possible, there are still limitations due to the low-level nature of the Node API.
The archives can not be modified so all Node APIs that can modify files will not work with asar
archives.
Though asar
archives are treated as directories, there are no actual directories in the filesystem, so you can never set the working directory to directories in asar
archives. Passing them as the cwd
option of some APIs will also cause errors.
Most fs
APIs can read a file or get a file's information from asar
archives without unpacking, but for some APIs that rely on passing the real file path to underlying system calls, Electron will extract the needed file into a temporary file and pass the path of the temporary file to the APIs to make them work. This adds a little overhead for those APIs.
APIs that requires extra unpacking are:
child_process.execFile
child_process.execFileSync
fs.open
fs.openSync
process.dlopen
- Used by require
on native modulesfs.stat
The Stats
object returned by fs.stat
and its friends on files in asar
archives is generated by guessing, because those files do not exist on the filesystem. So you should not trust the Stats
object except for getting file size and checking file type.
asar
ArchiveThere are Node APIs that can execute binaries like child_process.exec
, child_process.spawn
and child_process.execFile
, but only execFile
is supported to execute binaries inside asar
archive.
This is because exec
and spawn
accept command
instead of file
as input, and command
s are executed under shell. There is no reliable way to determine whether a command uses a file in asar archive, and even if we do, we can not be sure whether we can replace the path in command without side effects.
asar
ArchivesAs stated above, some Node APIs will unpack the file to the filesystem when called. Apart from the performance issues, various anti-virus scanners might be triggered by this behavior.
As a workaround, you can leave various files unpacked using the --unpack
option. In the following example, shared libraries of native Node.js modules will not be packed:
$ asar pack app app.asar --unpack *.node
After running the command, you will notice that a folder named app.asar.unpacked
was created together with the app.asar
file. It contains the unpacked files and should be shipped together with the app.asar
archive.
Enable apps to automatically update themselves.
Process: Main
See also: A detailed guide about how to implement updates in your application.
autoUpdater
is an EventEmitter.
Currently, only macOS and Windows are supported. There is no built-in support for auto-updater on Linux, so it is recommended to use the distribution's package manager to update your app.
In addition, there are some subtle differences on each platform:
On macOS, the autoUpdater
module is built upon Squirrel.Mac, meaning you don't need any special setup to make it work. For server-side requirements, you can read Server Support. Note that App Transport Security (ATS) applies to all requests made as part of the update process. Apps that need to disable ATS can add the NSAllowsArbitraryLoads
key to their app's plist.
Note: Your application must be signed for automatic updates on macOS. This is a requirement of Squirrel.Mac
.
On Windows, you have to install your app into a user's machine before you can use the autoUpdater
, so it is recommended that you use the electron-winstaller, electron-forge or the grunt-electron-installer package to generate a Windows installer.
When using electron-winstaller or electron-forge make sure you do not try to update your app the first time it runs (Also see this issue for more info). It's also recommended to use electron-squirrel-startup to get desktop shortcuts for your app.
The installer generated with Squirrel will create a shortcut icon with an Application User Model ID in the format of com.squirrel.PACKAGE_ID.YOUR_EXE_WITHOUT_DOT_EXE
, examples are com.squirrel.slack.Slack
and com.squirrel.code.Code
. You have to use the same ID for your app with app.setAppUserModelId
API, otherwise Windows will not be able to pin your app properly in task bar.
Unlike Squirrel.Mac, Windows can host updates on S3 or any other static file host. You can read the documents of Squirrel.Windows to get more details about how Squirrel.Windows works.
The autoUpdater
object emits the following events:
Returns:
error
ErrorEmitted when there is an error while updating.
Emitted when checking if an update has started.
Emitted when there is an available update. The update is downloaded automatically.
Emitted when there is no available update.
Returns:
event
EventreleaseNotes
StringreleaseName
StringreleaseDate
DateupdateURL
StringEmitted when an update has been downloaded.
On Windows only releaseName
is available.
Note: It is not strictly necessary to handle this event. A successfully downloaded update will still be applied the next time the application starts.
This event is emitted after a user calls quitAndInstall()
.
When this API is called, the before-quit
event is not emitted before all windows are closed. As a result you should listen to this event if you wish to perform actions before the windows are closed while a process is quitting, as well as listening to before-quit
.
The autoUpdater
object has the following methods:
autoUpdater.setFeedURL(options)
options
Objecturl
Stringheaders
Record<String, String> (optional) macOS - HTTP request headers.serverType
String (optional) macOS - Can be json
or default
, see the Squirrel.Mac README for more information.Sets the url
and initialize the auto updater.
autoUpdater.getFeedURL()
Returns String
- The current update feed URL.
autoUpdater.checkForUpdates()
Asks the server whether there is an update. You must call setFeedURL
before using this API.
autoUpdater.quitAndInstall()
Restarts the app and installs the update after it has been downloaded. It should only be called after update-downloaded
has been emitted.
Under the hood calling autoUpdater.quitAndInstall()
will close all application windows first, and automatically call app.quit()
after all windows have been closed.
Note: It is not strictly necessary to call this function to apply an update, as a successfully downloaded update will always be applied the next time the application starts.
To write automated tests for your Electron app, you will need a way to "drive" your application. Spectron is a commonly-used solution which lets you emulate user actions via WebDriver. However, it's also possible to write your own custom driver using node's builtin IPC-over-STDIO. The benefit of a custom driver is that it tends to require less overhead than Spectron, and lets you expose custom methods to your test suite.
To create a custom driver, we'll use Node.js' child_process API. The test suite will spawn the Electron process, then establish a simple messaging protocol:
const childProcess = require('child_process') const electronPath = require('electron') // spawn the process const env = { /* ... */ } const stdio = ['inherit', 'inherit', 'inherit', 'ipc'] const appProcess = childProcess.spawn(electronPath, ['./app'], { stdio, env }) // listen for IPC messages from the app appProcess.on('message', (msg) => { // ... }) // send an IPC message to the app appProcess.send({ my: 'message' })
From within the Electron app, you can listen for messages and send replies using the Node.js process API:
// listen for IPC messages from the test suite process.on('message', (msg) => { // ... }) // send an IPC message to the test suite process.send({ my: 'message' })
We can now communicate from the test suite to the Electron app using the appProcess
object.
For convenience, you may want to wrap appProcess
in a driver object that provides more high-level functions. Here is an example of how you can do this:
class TestDriver { constructor ({ path, args, env }) { this.rpcCalls = [] // start child process env.APP_TEST_DRIVER = 1 // let the app know it should listen for messages this.process = childProcess.spawn(path, args, { stdio: ['inherit', 'inherit', 'inherit', 'ipc'], env }) // handle rpc responses this.process.on('message', (message) => { // pop the handler const rpcCall = this.rpcCalls[message.msgId] if (!rpcCall) return this.rpcCalls[message.msgId] = null // reject/resolve if (message.reject) rpcCall.reject(message.reject) else rpcCall.resolve(message.resolve) }) // wait for ready this.isReady = this.rpc('isReady').catch((err) => { console.error('Application failed to start', err) this.stop() process.exit(1) }) } // simple RPC call // to use: driver.rpc('method', 1, 2, 3).then(...) async rpc (cmd, ...args) { // send rpc request const msgId = this.rpcCalls.length this.process.send({ msgId, cmd, args }) return new Promise((resolve, reject) => this.rpcCalls.push({ resolve, reject })) } stop () { this.process.kill() } }
In the app, you'd need to write a simple handler for the RPC calls:
if (process.env.APP_TEST_DRIVER) { process.on('message', onMessage) } async function onMessage ({ msgId, cmd, args }) { let method = METHODS[cmd] if (!method) method = () => new Error('Invalid method: ' + cmd) try { const resolve = await method(...args) process.send({ msgId, resolve }) } catch (err) { const reject = { message: err.message, stack: err.stack, name: err.name } process.send({ msgId, reject }) } } const METHODS = { isReady () { // do any setup needed return true } // define your RPC-able methods here }
Then, in your test suite, you can use your test-driver as follows:
const test = require('ava') const electronPath = require('electron') const app = new TestDriver({ path: electronPath, args: ['./app'], env: { NODE_ENV: 'test' } }) test.before(async t => { await app.isReady }) test.after.always('cleanup', async t => { await app.stop() })
Electron CI on Windows uses AppVeyor, which in turn uses Azure VM images to run. Occasionally, these VM images need to be updated due to changes in Chromium requirements. In order to update you will need PowerShell and the Azure PowerShell module.
Occasionally we need to update these images owing to changes in Chromium or other miscellaneous build requirement changes.
Example Use Case:
* We need `VS15.9` and we have `VS15.7` installed; this would require us to update an Azure image.
Identify the image you wish to modify.
Get the Azure storage account key
appveyorlibccbuilds
Disk Storage Account Name you'd look for appveyorlibccbuilds
in the list of storage accounts @ Home < Storage AccountsAccess Keys
, and then you can use any of the keys present in the list.Get the full virtual machine image URI from Azure
$ACCT_NAME
< Blobs < ImagesCopy the image using the Copy Master Image PowerShell script.
(images)
libcc-20core-vs2017-15.9-2019-04-15.vhd
Spin up a new VM using the Create Master VM from VHD PowerShell.
ps1
file with ./create_master_vm_from_vhd.ps1
Standard_F32s_v2
East US
Log back into Azure and find the VM you just created in Home < Virtual Machines < $YOUR_NEW_VM
Using Microsoft Remote Desktop, click Connect
to connect to the VM.
AppVeyor Enterprise master VM
credentials.Modify the VM as required.
Shut down the VM and then delete it in Azure.
Add the new image to the Appveyor Cloud settings or modify an existing image to point to the new VHD.
deviceName
StringdeviceId
StringElectron development is unopinionated - there is no "one true way" to develop, build, package, or release an Electron application. Additional features for Electron, both for build- and run-time, can usually be found on npm in individual packages, allowing developers to build both the app and build pipeline they need.
That level of modularity and extendability ensures that all developers working with Electron, both big and small in team-size, are never restricted in what they can or cannot do at any time during their development lifecycle. However, for many developers, one of the community-driven boilerplates or command line tools might make it dramatically easier to compile, package, and release an app.
A boilerplate is only a starting point - a canvas, so to speak - from which you build your application. They usually come in the form of a repository you can clone and customize to your heart's content.
A command line tool on the other hand continues to support you throughout the development and release. They are more helpful and supportive but enforce guidelines on how your code should be structured and built. Especially for beginners, using a command line tool is likely to be helpful.
A "complete tool for building modern Electron applications". Electron Forge unifies the existing (and well maintained) build tools for Electron development into a cohesive package so that anyone can jump right in to Electron development.
Forge comes with a ready-to-use template using Webpack as a bundler. It includes an example typescript configuration and provides two configuration files to enable easy customization. It uses the same core modules used by the greater Electron community (like electron-packager
) – changes made by Electron maintainers (like Slack) benefit Forge's users, too.
You can find more information and documentation on electronforge.io.
A "complete solution to package and build a ready-for-distribution Electron app" that focuses on an integrated experience. electron-builder
adds one single dependency focused on simplicity and manages all further requirements internally.
electron-builder
replaces features and modules used by the Electron maintainers (such as the auto-updater) with custom ones. They are generally tighter integrated but will have less in common with popular Electron apps like Atom, Visual Studio Code, or Slack.
You can find more information and documentation in the repository.
If you don't want any tools but only a solid boilerplate to build from, CT Lin's electron-react-boilerplate
might be worth a look. It's quite popular in the community and uses electron-builder
internally.
The "Awesome Electron" list contains more tools and boilerplates to choose from. If you find the length of the list intimidating, don't forget that adding tools as you go along is a valid approach, too.
Breaking changes will be documented here, and deprecation warnings added to JS code where possible, at least one major version before the change is made.
This document uses the following convention to categorize breaking changes:
shell.moveItemToTrash()
The deprecated synchronous shell.moveItemToTrash()
API has been removed. Use the asynchronous shell.trashItem()
instead.
// Removed in Electron 13 shell.moveItemToTrash(path) // Replace with shell.trashItem(path).then(/* ... */)
Chromium has removed support for Flash, and so we must follow suit. See Chromium's Flash Roadmap for more details.
contextIsolation
defaults to true
In Electron 12, contextIsolation
will be enabled by default. To restore the previous behavior, contextIsolation: false
must be specified in WebPreferences.
We recommend having contextIsolation enabled for the security of your application.
For more details see: https://github.com/electron/electron/issues/23506
crashReporter
methods in the renderer processThe following crashReporter
methods are no longer available in the renderer process:
crashReporter.start
crashReporter.getLastCrashReport
crashReporter.getUploadedReports
crashReporter.getUploadToServer
crashReporter.setUploadToServer
crashReporter.getCrashesDirectory
They should be called only from the main process.
See #23265 for more details.
crashReporter.start({ compress: true })
The default value of the compress
option to crashReporter.start
has changed from false
to true
. This means that crash dumps will be uploaded to the crash ingestion server with the Content-Encoding: gzip
header, and the body will be compressed.
If your crash ingestion server does not support compressed payloads, you can turn off compression by specifying { compress: false }
in the crash reporter options.
remote
moduleThe remote
module is deprecated in Electron 12, and will be removed in Electron 14. It is replaced by the @electron/remote
module.
// Deprecated in Electron 12: const { BrowserWindow } = require('electron').remote
// Replace with: const { BrowserWindow } = require('@electron/remote') // In the main process: require('@electron/remote/main').initialize()
shell.moveItemToTrash()
The synchronous shell.moveItemToTrash()
has been replaced by the new, asynchronous shell.trashItem()
.
// Deprecated in Electron 12 shell.moveItemToTrash(path) // Replace with shell.trashItem(path).then(/* ... */)
BrowserView.{destroy, fromId, fromWebContents, getAllViews}
and id
property of BrowserView
The experimental APIs BrowserView.{destroy, fromId, fromWebContents, getAllViews}
have now been removed. Additionally, the id
property of BrowserView
has also been removed.
For more detailed information, see #23578.
companyName
argument to crashReporter.start()
The companyName
argument to crashReporter.start()
, which was previously required, is now optional, and further, is deprecated. To get the same behavior in a non-deprecated way, you can pass a companyName
value in globalExtra
.
// Deprecated in Electron 10 crashReporter.start({ companyName: 'Umbrella Corporation' }) // Replace with crashReporter.start({ globalExtra: { _companyName: 'Umbrella Corporation' } })
crashReporter.getCrashesDirectory()
The crashReporter.getCrashesDirectory
method has been deprecated. Usage should be replaced by app.getPath('crashDumps')
.
// Deprecated in Electron 10 crashReporter.getCrashesDirectory() // Replace with app.getPath('crashDumps')
crashReporter
methods in the renderer processCalling the following crashReporter
methods from the renderer process is deprecated:
crashReporter.start
crashReporter.getLastCrashReport
crashReporter.getUploadedReports
crashReporter.getUploadToServer
crashReporter.setUploadToServer
crashReporter.getCrashesDirectory
The only non-deprecated methods remaining in the crashReporter
module in the renderer are addExtraParameter
, removeExtraParameter
and getParameters
.
All above methods remain non-deprecated when called from the main process.
See #23265 for more details.
crashReporter.start({ compress: false })
Setting { compress: false }
in crashReporter.start
is deprecated. Nearly all crash ingestion servers support gzip compression. This option will be removed in a future version of Electron.
The affinity
option when constructing a new BrowserWindow
will be removed as part of our plan to more closely align with Chromium's process model for security, performance and maintainability.
For more detailed information see #18397.
enableRemoteModule
defaults to false
In Electron 9, using the remote module without explicitly enabling it via the enableRemoteModule
WebPreferences option began emitting a warning. In Electron 10, the remote module is now disabled by default. To use the remote module, enableRemoteModule: true
must be specified in WebPreferences:
const w = new BrowserWindow({ webPreferences: { enableRemoteModule: true } })
We recommend moving away from the remote module.
protocol.unregisterProtocol
protocol.uninterceptProtocol
The APIs are now synchronous and the optional callback is no longer needed.
// Deprecated protocol.unregisterProtocol(scheme, () => { /* ... */ }) // Replace with protocol.unregisterProtocol(scheme)
protocol.registerFileProtocol
protocol.registerBufferProtocol
protocol.registerStringProtocol
protocol.registerHttpProtocol
protocol.registerStreamProtocol
protocol.interceptFileProtocol
protocol.interceptStringProtocol
protocol.interceptBufferProtocol
protocol.interceptHttpProtocol
protocol.interceptStreamProtocol
The APIs are now synchronous and the optional callback is no longer needed.
// Deprecated protocol.registerFileProtocol(scheme, handler, () => { /* ... */ }) // Replace with protocol.registerFileProtocol(scheme, handler)
The registered or intercepted protocol does not have effect on current page until navigation happens.
protocol.isProtocolHandled
This API is deprecated and users should use protocol.isProtocolRegistered
and protocol.isProtocolIntercepted
instead.
// Deprecated protocol.isProtocolHandled(scheme).then(() => { /* ... */ }) // Replace with const isRegistered = protocol.isProtocolRegistered(scheme) const isIntercepted = protocol.isProtocolIntercepted(scheme)
As of Electron 9 we do not allow loading of non-context-aware native modules in the renderer process. This is to improve security, performance and maintainability of Electron as a project.
If this impacts you, you can temporarily set app.allowRendererProcessReuse
to false
to revert to the old behavior. This flag will only be an option until Electron 11 so you should plan to update your native modules to be context aware.
For more detailed information see #18397.
<webview>.getWebContents()
This API, which was deprecated in Electron 8.0, is now removed.
// 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.
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.
shell.openItem
is now shell.openPath
The shell.openItem
API has been replaced with an asynchronous shell.openPath
API. You can see the original API proposal and reasoning here.
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, 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.
undefined
.// 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
.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
.null
s.Date
objects will be transferred as Date
objects, instead of being converted to their ISO string representation.Uint8Array
, Uint16Array
, Uint32Array
and so on) will be transferred as such, instead of being converted to Node.js Buffer
.Buffer
objects will be transferred as Uint8Array
s. You can convert a Uint8Array
back to a Node.js Buffer
by wrapping the underlying ArrayBuffer
: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.
<webview>.getWebContents()
This API is implemented using the remote
module, which has both performance and security implications. Therefore its usage should be explicit.
// 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.
// 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.
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()
no longer accepts optionsThe session.clearAuthCache
API no longer accepts options for what to clear, and instead unconditionally clears the whole cache.
// Deprecated session.clearAuthCache({ type: 'password' }) // Replace with session.clearAuthCache()
powerMonitor.querySystemIdleState
is now powerMonitor.getSystemIdleState
// Removed in Electron 7.0 powerMonitor.querySystemIdleState(threshold, callback) // Replace with synchronous API const idleState = powerMonitor.getSystemIdleState(threshold)
powerMonitor.querySystemIdleTime
is now powerMonitor.getSystemIdleTime
// Removed in Electron 7.0 powerMonitor.querySystemIdleTime(callback) // Replace with synchronous API const idleTime = powerMonitor.getSystemIdleTime()
webFrame.setIsolatedWorldInfo
replaces separate methods// 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' })
marked
property on getBlinkMemoryInfo
This property was removed in Chromium 77, and as such is no longer available.
webkitdirectory
attribute for <input type="file"/>
now lists directory contentsThe 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).
As an illustration, take a folder with this structure:
folder ├── file1 ├── file2 └── file3
In Electron <=6, this would return a FileList
with a File
object for:
path/to/folder
In Electron 7, this now returns a FileList
with a File
object for:
/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).
win.setMenu(null)
is now win.removeMenu()
// Deprecated win.setMenu(null) // Replace with win.removeMenu()
contentTracing.getTraceBufferUsage()
is now a promise// Deprecated contentTracing.getTraceBufferUsage((percentage, value) => { // do something }) // Replace with contentTracing.getTraceBufferUsage().then(infoObject => { // infoObject has percentage and value fields })
electron.screen
in the renderer process should be accessed via remote
// Deprecated require('electron').screen // Replace with require('electron').remote.screen
require()
ing node builtins in sandboxed renderers no longer implicitly loads the remote
version// 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
replaced with powerMonitor.getSystemIdleState
// Deprecated powerMonitor.querySystemIdleState(threshold, callback) // Replace with synchronous API const idleState = powerMonitor.getSystemIdleState(threshold)
powerMonitor.querySystemIdleTime
replaced with powerMonitor.getSystemIdleTime
// Deprecated powerMonitor.querySystemIdleTime(callback) // Replace with synchronous API const idleTime = powerMonitor.getSystemIdleTime()
app.enableMixedSandbox()
is no longer needed// Deprecated app.enableMixedSandbox()
Mixed-sandbox mode is now enabled by default.
Tray.setHighlightMode
Under macOS Catalina our former Tray implementation breaks. Apple's native substitute doesn't support changing the highlighting behavior.
// Deprecated tray.setHighlightMode(mode) // API will be removed in v7.0 without replacement.
nodeIntegration
and webviewTag
default to false, contextIsolation
defaults to trueThe 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
const w = new BrowserWindow({ webPreferences: { webviewTag: true } })
nodeIntegration
in child windows opened via nativeWindowOpen
Child windows opened with the nativeWindowOpen
option will always have Node.js integration disabled, unless nodeIntegrationInSubFrames
is true
.
Renderer process APIs webFrame.registerURLSchemeAsPrivileged
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.setIsolatedWorld*
replaced with webFrame.setIsolatedWorldInfo
// 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
now takes an asynchronous callbackThe spellCheck
callback is now asynchronous, and autoCorrectWord
parameter has been removed.
// 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))) } })
The following list includes the breaking API changes made in Electron 4.0.
app.makeSingleInstance
// Deprecated app.makeSingleInstance((argv, cwd) => { /* ... */ }) // Replace with app.requestSingleInstanceLock() app.on('second-instance', (event, argv, cwd) => { /* ... */ })
app.releaseSingleInstance
// Deprecated app.releaseSingleInstance() // Replace with app.releaseSingleInstanceLock()
app.getGPUInfo
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 for more.
The following list includes the breaking API changes in Electron 3.0.
app
// Deprecated app.getAppMemoryInfo() // Replace with app.getAppMetrics() // Deprecated const metrics = app.getAppMetrics() const { memory } = metrics[0] // Deprecated property
BrowserWindow
// Deprecated const optionsA = { webPreferences: { blinkFeatures: '' } } const windowA = new BrowserWindow(optionsA) // Replace with const optionsB = { webPreferences: { enableBlinkFeatures: '' } } const 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
// 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
// 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
// Deprecated nativeImage.createFromBuffer(buffer, 1.0) // Replace with nativeImage.createFromBuffer(buffer, { scaleFactor: 1.0 })
process
// Deprecated const info = process.getProcessMemoryInfo()
screen
// Deprecated screen.getMenuBarHeight() // Replace with screen.getPrimaryDisplay().workArea
session
// Deprecated ses.setCertificateVerifyProc((hostname, certificate, callback) => { callback(true) }) // Replace with ses.setCertificateVerifyProc((request, callback) => { callback(0) })
Tray
// Deprecated tray.setHighlightMode(true) // Replace with tray.setHighlightMode('on') // Deprecated tray.setHighlightMode(false) // Replace with tray.setHighlightMode('off')
webContents
// Deprecated webContents.openDevTools({ detach: true }) // Replace with webContents.openDevTools({ mode: 'detach' }) // Removed webContents.setSize(options) // There is no replacement for this API
webFrame
// Deprecated webFrame.registerURLSchemeAsSecure('app') // Replace with protocol.registerStandardSchemes(['app'], { secure: true }) // Deprecated webFrame.registerURLSchemeAsPrivileged('app', { secure: true }) // Replace with protocol.registerStandardSchemes(['app'], { secure: true })
<webview>
// 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 */ }
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
The following list includes the breaking API changes made in Electron 2.0.
BrowserWindow
// Deprecated const optionsA = { titleBarStyle: 'hidden-inset' } const windowA = new BrowserWindow(optionsA) // Replace with const optionsB = { titleBarStyle: 'hiddenInset' } const windowB = new BrowserWindow(optionsB)
menu
// Removed menu.popup(browserWindow, 100, 200, 2) // Replaced with menu.popup(browserWindow, { x: 100, y: 200, positioningItem: 2 })
nativeImage
// 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
// Removed webContents.setZoomLevelLimits(1, 2) // Replaced with webContents.setVisualZoomLevelLimits(1, 2)
webFrame
// Removed webFrame.setZoomLevelLimits(1, 2) // Replaced with webFrame.setVisualZoomLevelLimits(1, 2)
<webview>
// Removed webview.setZoomLevelLimits(1, 2) // Replaced with webview.setVisualZoomLevelLimits(1, 2)
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 and 7189.
Create and control views.
Process: Main
A BrowserView
can be used to embed additional web content into a BrowserWindow
. It is like a child window, except that it is positioned relative to its owning window. It is meant to be an alternative to the webview
tag.
// In the main process. const { BrowserView, BrowserWindow } = require('electron') const win = new BrowserWindow({ width: 800, height: 600 }) const view = new BrowserView() win.setBrowserView(view) view.setBounds({ x: 0, y: 0, width: 300, height: 300 }) view.webContents.loadURL('https://electronjs.org')
new BrowserView([options])
Experimental
options
Object (optional)webPreferences
Object (optional) - See BrowserWindow.Objects created with new BrowserView
have the following properties:
view.webContents
Experimental
A WebContents
object owned by this view.
Objects created with new BrowserView
have the following instance methods:
view.setAutoResize(options)
Experimental
options
Objectwidth
Boolean (optional) - If true
, the view's width will grow and shrink together with the window. false
by default.height
Boolean (optional) - If true
, the view's height will grow and shrink together with the window. false
by default.horizontal
Boolean (optional) - If true
, the view's x position and width will grow and shrink proportionally with the window. false
by default.vertical
Boolean (optional) - If true
, the view's y position and height will grow and shrink proportionally with the window. false
by default.view.setBounds(bounds)
Experimental
bounds
Rectangle
Resizes and moves the view to the supplied bounds relative to the window.
view.getBounds()
Experimental
Returns Rectangle
The bounds
of this BrowserView instance as Object
.
view.setBackgroundColor(color)
Experimental
color
String - Color in #aarrggbb
or #argb
form. The alpha channel is optional.Create and control browser windows.
Process: Main
// In the main process. const { BrowserWindow } = require('electron') // Or use `remote` from the renderer process. // const { BrowserWindow } = require('electron').remote const win = new BrowserWindow({ width: 800, height: 600 }) // Load a remote URL win.loadURL('https://github.com') // Or load a local HTML file win.loadURL(`file://${__dirname}/app/index.html`)
To create a window without chrome, or a transparent window in arbitrary shape, you can use the Frameless Window API.
When loading a page in the window directly, users may see the page load incrementally, which is not a good experience for a native app. To make the window display without visual flash, there are two solutions for different situations.
ready-to-show
eventWhile loading the page, the ready-to-show
event will be emitted when the renderer process has rendered the page for the first time if the window has not been shown yet. Showing the window after this event will have no visual flash:
const { BrowserWindow } = require('electron') const win = new BrowserWindow({ show: false }) win.once('ready-to-show', () => { win.show() })
This event is usually emitted after the did-finish-load
event, but for pages with many remote resources, it may be emitted before the did-finish-load
event.
Please note that using this event implies that the renderer will be considered "visible" and paint even though show
is false. This event will never fire if you use paintWhenInitiallyHidden: false
backgroundColor
For a complex app, the ready-to-show
event could be emitted too late, making the app feel slow. In this case, it is recommended to show the window immediately, and use a backgroundColor
close to your app's background:
const { BrowserWindow } = require('electron') const win = new BrowserWindow({ backgroundColor: '#2e2c29' }) win.loadURL('https://github.com')
Note that even for apps that use ready-to-show
event, it is still recommended to set backgroundColor
to make app feel more native.
By using parent
option, you can create child windows:
const { BrowserWindow } = require('electron') const top = new BrowserWindow() const child = new BrowserWindow({ parent: top }) child.show() top.show()
The child
window will always show on top of the top
window.
A modal window is a child window that disables parent window, to create a modal window, you have to set both parent
and modal
options:
const { BrowserWindow } = require('electron') const child = new BrowserWindow({ parent: top, modal: true, show: false }) child.loadURL('https://github.com') child.once('ready-to-show', () => { child.show() })
The Page Visibility API works as follows:
hidden
. On other platforms, the visibility state will be hidden
only when the window is minimized or explicitly hidden with win.hide()
.BrowserWindow
is created with show: false
, the initial visibility state will be visible
despite the window actually being hidden.backgroundThrottling
is disabled, the visibility state will remain visible
even if the window is minimized, occluded, or hidden.It is recommended that you pause expensive operations when the visibility state is hidden
in order to minimize power consumption.
dialog
.Create and control browser windows.
Process: Main
BrowserWindow
is an EventEmitter.
It creates a new BrowserWindow
with native properties as set by the options
.
new BrowserWindow([options])
options
Object (optional)width
Integer (optional) - Window's width in pixels. Default is 800
.height
Integer (optional) - Window's height in pixels. Default is 600
.x
Integer (optional) - (required if y is used) Window's left offset from screen. Default is to center the window.y
Integer (optional) - (required if x is used) Window's top offset from screen. Default is to center the window.useContentSize
Boolean (optional) - The width
and height
would be used as web page's size, which means the actual window's size will include window frame's size and be slightly larger. Default is false
.center
Boolean (optional) - Show window in the center of the screen.minWidth
Integer (optional) - Window's minimum width. Default is 0
.minHeight
Integer (optional) - Window's minimum height. Default is 0
.maxWidth
Integer (optional) - Window's maximum width. Default is no limit.maxHeight
Integer (optional) - Window's maximum height. Default is no limit.resizable
Boolean (optional) - Whether window is resizable. Default is true
.movable
Boolean (optional) - Whether window is movable. This is not implemented on Linux. Default is true
.minimizable
Boolean (optional) - Whether window is minimizable. This is not implemented on Linux. Default is true
.maximizable
Boolean (optional) - Whether window is maximizable. This is not implemented on Linux. Default is true
.closable
Boolean (optional) - Whether window is closable. This is not implemented on Linux. Default is true
.focusable
Boolean (optional) - Whether the window can be focused. Default is true
. On Windows setting focusable: false
also implies setting skipTaskbar: true
. On Linux setting focusable: false
makes the window stop interacting with wm, so the window will always stay on top in all workspaces.alwaysOnTop
Boolean (optional) - Whether the window should always stay on top of other windows. Default is false
.fullscreen
Boolean (optional) - Whether the window should show in fullscreen. When explicitly set to false
the fullscreen button will be hidden or disabled on macOS. Default is false
.fullscreenable
Boolean (optional) - Whether the window can be put into fullscreen mode. On macOS, also whether the maximize/zoom button should toggle full screen mode or maximize window. Default is true
.simpleFullscreen
Boolean (optional) - Use pre-Lion fullscreen on macOS. Default is false
.skipTaskbar
Boolean (optional) - Whether to show the window in taskbar. Default is false
.kiosk
Boolean (optional) - Whether the window is in kiosk mode. Default is false
.title
String (optional) - Default window title. Default is "Electron"
. If the HTML tag <title>
is defined in the HTML file loaded by loadURL()
, this property will be ignored.icon
(NativeImage | String) (optional) - The window icon. On Windows it is recommended to use ICO
icons to get best visual effects, you can also leave it undefined so the executable's icon will be used.show
Boolean (optional) - Whether window should be shown when created. Default is true
.paintWhenInitiallyHidden
Boolean (optional) - Whether the renderer should be active when show
is false
and it has just been created. In order for document.visibilityState
to work correctly on first load with show: false
you should set this to false
. Setting this to false
will cause the ready-to-show
event to not fire. Default is true
.frame
Boolean (optional) - Specify false
to create a Frameless Window. Default is true
.parent
BrowserWindow (optional) - Specify parent window. Default is null
.modal
Boolean (optional) - Whether this is a modal window. This only works when the window is a child window. Default is false
.acceptFirstMouse
Boolean (optional) - Whether the web view accepts a single mouse-down event that simultaneously activates the window. Default is false
.disableAutoHideCursor
Boolean (optional) - Whether to hide cursor when typing. Default is false
.autoHideMenuBar
Boolean (optional) - Auto hide the menu bar unless the Alt
key is pressed. Default is false
.enableLargerThanScreen
Boolean (optional) - Enable the window to be resized larger than screen. Only relevant for macOS, as other OSes allow larger-than-screen windows by default. Default is false
.backgroundColor
String (optional) - Window's background color as a hexadecimal value, like #66CD00
or #FFF
or #80FFFFFF
(alpha in #AARRGGBB format is supported if transparent
is set to true
). Default is #FFF
(white).hasShadow
Boolean (optional) - Whether window should have a shadow. Default is true
.opacity
Number (optional) - Set the initial opacity of the window, between 0.0 (fully transparent) and 1.0 (fully opaque). This is only implemented on Windows and macOS.darkTheme
Boolean (optional) - Forces using dark theme for the window, only works on some GTK+3 desktop environments. Default is false
.transparent
Boolean (optional) - Makes the window transparent. Default is false
. On Windows, does not work unless the window is frameless.type
String (optional) - The type of window, default is normal window. See more about this below.visualEffectState
String (optional) - Specify how the material appearance should reflect window activity state on macOS. Must be used with the vibrancy
property. Possible values are:followWindow
- The backdrop should automatically appear active when the window is active, and inactive when it is not. This is the default.active
- The backdrop should always appear active.inactive
- The backdrop should always appear inactive.titleBarStyle
String (optional) - The style of window title bar. Default is default
. Possible values are:default
- Results in the standard gray opaque Mac title bar.hidden
- Results in a hidden title bar and a full size content window, yet the title bar still has the standard window controls ("traffic lights") in the top left.hiddenInset
- Results in a hidden title bar with an alternative look where the traffic light buttons are slightly more inset from the window edge.customButtonsOnHover
Boolean (optional) - Draw custom close, and minimize buttons on macOS frameless windows. These buttons will not display unless hovered over in the top left of the window. These custom buttons prevent issues with mouse events that occur with the standard window toolbar buttons. Note: This option is currently experimental.trafficLightPosition
Point (optional) - Set a custom position for the traffic light buttons. Can only be used with titleBarStyle
set to hidden
fullscreenWindowTitle
Boolean (optional) - Shows the title in the title bar in full screen mode on macOS for all titleBarStyle
options. Default is false
.thickFrame
Boolean (optional) - Use WS_THICKFRAME
style for frameless windows on Windows, which adds standard window frame. Setting it to false
will remove window shadow and window animations. Default is true
.vibrancy
String (optional) - Add a type of vibrancy effect to the window, only on macOS. Can be appearance-based
, light
, dark
, titlebar
, selection
, menu
, popover
, sidebar
, medium-light
, ultra-dark
, header
, sheet
, window
, hud
, fullscreen-ui
, tooltip
, content
, under-window
, or under-page
. Please note that using frame: false
in combination with a vibrancy value requires that you use a non-default titleBarStyle
as well. Also note that appearance-based
, light
, dark
, medium-light
, and ultra-dark
have been deprecated and will be removed in an upcoming version of macOS.zoomToPageWidth
Boolean (optional) - Controls the behavior on macOS when option-clicking the green stoplight button on the toolbar or by clicking the Window > Zoom menu item. If true
, the window will grow to the preferred width of the web page when zoomed, false
will cause it to zoom to the width of the screen. This will also affect the behavior when calling maximize()
directly. Default is false
.tabbingIdentifier
String (optional) - Tab group name, allows opening the window as a native tab on macOS 10.12+. Windows with the same tabbing identifier will be grouped together. This also adds a native new tab button to your window's tab bar and allows your app
and window to receive the new-window-for-tab
event.webPreferences
Object (optional) - Settings of web page's features.devTools
Boolean (optional) - Whether to enable DevTools. If it is set to false
, can not use BrowserWindow.webContents.openDevTools()
to open DevTools. Default is true
.nodeIntegration
Boolean (optional) - Whether node integration is enabled. Default is false
.nodeIntegrationInWorker
Boolean (optional) - Whether node integration is enabled in web workers. Default is false
. More about this can be found in Multithreading.nodeIntegrationInSubFrames
Boolean (optional) - Experimental option for enabling Node.js support in sub-frames such as iframes and child windows. All your preloads will load for every iframe, you can use process.isMainFrame
to determine if you are in the main frame or not.preload
String (optional) - Specifies a script that will be loaded before other scripts run in the page. This script will always have access to node APIs no matter whether node integration is turned on or off. The value should be the absolute file path to the script. When node integration is turned off, the preload script can reintroduce Node global symbols back to the global scope. See example here.sandbox
Boolean (optional) - If set, this will sandbox the renderer associated with the window, making it compatible with the Chromium OS-level sandbox and disabling the Node.js engine. This is not the same as the nodeIntegration
option and the APIs available to the preload script are more limited. Read more about the option here.enableRemoteModule
Boolean (optional) - Whether to enable the remote
module. Default is false
.session
Session (optional) - Sets the session used by the page. Instead of passing the Session object directly, you can also choose to use the partition
option instead, which accepts a partition string. When both session
and partition
are provided, session
will be preferred. Default is the default session.partition
String (optional) - Sets the session used by the page according to the session's partition string. If partition
starts with persist:
, the page will use a persistent session available to all pages in the app with the same partition
. If there is no persist:
prefix, the page will use an in-memory session. By assigning the same partition
, multiple pages can share the same session. Default is the default session.affinity
String (optional) - When specified, web pages with the same affinity
will run in the same renderer process. Note that due to reusing the renderer process, certain webPreferences
options will also be shared between the web pages even when you specified different values for them, including but not limited to preload
, sandbox
and nodeIntegration
. So it is suggested to use exact same webPreferences
for web pages with the same affinity
. Deprecated
zoomFactor
Number (optional) - The default zoom factor of the page, 3.0
represents 300%
. Default is 1.0
.javascript
Boolean (optional) - Enables JavaScript support. Default is true
.webSecurity
Boolean (optional) - When false
, it will disable the same-origin policy (usually using testing websites by people), and set allowRunningInsecureContent
to true
if this options has not been set by user. Default is true
.allowRunningInsecureContent
Boolean (optional) - Allow an https page to run JavaScript, CSS or plugins from http URLs. Default is false
.images
Boolean (optional) - Enables image support. Default is true
.textAreasAreResizable
Boolean (optional) - Make TextArea elements resizable. Default is true
.webgl
Boolean (optional) - Enables WebGL support. Default is true
.plugins
Boolean (optional) - Whether plugins should be enabled. Default is false
.experimentalFeatures
Boolean (optional) - Enables Chromium's experimental features. Default is false
.scrollBounce
Boolean (optional) - Enables scroll bounce (rubber banding) effect on macOS. Default is false
.enableBlinkFeatures
String (optional) - A list of feature strings separated by ,
, like CSSVariables,KeyboardEventKey
to enable. The full list of supported feature strings can be found in the RuntimeEnabledFeatures.json5 file.disableBlinkFeatures
String (optional) - A list of feature strings separated by ,
, like CSSVariables,KeyboardEventKey
to disable. The full list of supported feature strings can be found in the RuntimeEnabledFeatures.json5 file.defaultFontFamily
Object (optional) - Sets the default font for the font-family.standard
String (optional) - Defaults to Times New Roman
.serif
String (optional) - Defaults to Times New Roman
.sansSerif
String (optional) - Defaults to Arial
.monospace
String (optional) - Defaults to Courier New
.cursive
String (optional) - Defaults to Script
.fantasy
String (optional) - Defaults to Impact
.defaultFontSize
Integer (optional) - Defaults to 16
.defaultMonospaceFontSize
Integer (optional) - Defaults to 13
.minimumFontSize
Integer (optional) - Defaults to 0
.defaultEncoding
String (optional) - Defaults to ISO-8859-1
.backgroundThrottling
Boolean (optional) - Whether to throttle animations and timers when the page becomes background. This also affects the Page Visibility API. Defaults to true
.offscreen
Boolean (optional) - Whether to enable offscreen rendering for the browser window. Defaults to false
. See the offscreen rendering tutorial for more details.contextIsolation
Boolean (optional) - Whether to run Electron APIs and the specified preload
script in a separate JavaScript context. Defaults to false
. The context that the preload
script runs in will still have full access to the document
and window
globals but it will use its own set of JavaScript builtins (Array
, Object
, JSON
, etc.) and will be isolated from any changes made to the global environment by the loaded page. The Electron API will only be available in the preload
script and not the loaded page. This option should be used when loading potentially untrusted remote content to ensure the loaded content cannot tamper with the preload
script and any Electron APIs being used. This option uses the same technique used by Chrome Content Scripts. You can access this context in the dev tools by selecting the 'Electron Isolated Context' entry in the combo box at the top of the Console tab.worldSafeExecuteJavaScript
Boolean (optional) - If true, values returned from webFrame.executeJavaScript
will be sanitized to ensure JS values can't unsafely cross between worlds when using contextIsolation
. The default is false
. In Electron 12, the default will be changed to true
. Deprecated
nativeWindowOpen
Boolean (optional) - Whether to use native window.open()
. Defaults to false
. Child windows will always have node integration disabled unless nodeIntegrationInSubFrames
is true. Note: This option is currently experimental.webviewTag
Boolean (optional) - Whether to enable the <webview>
tag. Defaults to false
. Note: The preload
script configured for the <webview>
will have node integration enabled when it is executed so you should ensure remote/untrusted content is not able to create a <webview>
tag with a possibly malicious preload
script. You can use the will-attach-webview
event on webContents to strip away the preload
script and to validate or alter the <webview>
's initial settings.additionalArguments
String[] (optional) - A list of strings that will be appended to process.argv
in the renderer process of this app. Useful for passing small bits of data down to renderer process preload scripts.safeDialogs
Boolean (optional) - Whether to enable browser style consecutive dialog protection. Default is false
.safeDialogsMessage
String (optional) - The message to display when consecutive dialog protection is triggered. If not defined the default message would be used, note that currently the default message is in English and not localized.disableDialogs
Boolean (optional) - Whether to disable dialogs completely. Overrides safeDialogs
. Default is false
.navigateOnDragDrop
Boolean (optional) - Whether dragging and dropping a file or link onto the page causes a navigation. Default is false
.autoplayPolicy
String (optional) - Autoplay policy to apply to content in the window, can be no-user-gesture-required
, user-gesture-required
, document-user-activation-required
. Defaults to no-user-gesture-required
.disableHtmlFullscreenWindowResize
Boolean (optional) - Whether to prevent the window from resizing when entering HTML Fullscreen. Default is false
.accessibleTitle
String (optional) - An alternative title string provided only to accessibility tools such as screen readers. This string is not directly visible to users.spellcheck
Boolean (optional) - Whether to enable the builtin spellchecker. Default is true
.enableWebSQL
Boolean (optional) - Whether to enable the WebSQL api. Default is true
.v8CacheOptions
String (optional) - Enforces the v8 code caching policy used by blink. Accepted values arenone
- Disables code cachingcode
- Heuristic based code cachingbypassHeatCheck
- Bypass code caching heuristics but with lazy compilationbypassHeatCheckAndEagerCompile
- Same as above except compilation is eager. Default policy is code
.When setting minimum or maximum window size with minWidth
/maxWidth
/ minHeight
/maxHeight
, it only constrains the users. It won't prevent you from passing a size that does not follow size constraints to setBounds
/setSize
or to the constructor of BrowserWindow
.
The possible values and behaviors of the type
option are platform dependent. Possible values are:
desktop
, dock
, toolbar
, splash
, notification
.desktop
, textured
.textured
type adds metal gradient appearance (NSTexturedBackgroundWindowMask
).desktop
type places the window at the desktop background window level (kCGDesktopWindowLevel - 1
). Note that desktop window will not receive focus, keyboard or mouse events, but you can use globalShortcut
to receive input sparingly.toolbar
.Objects created with new BrowserWindow
emit the following events:
Note: Some events are only available on specific operating systems and are labeled as such.
Returns:
event
Eventtitle
StringexplicitSet
BooleanEmitted when the document changed its title, calling event.preventDefault()
will prevent the native window's title from changing. explicitSet
is false when title is synthesized from file URL.
Returns:
event
EventEmitted when the window is going to be closed. It's emitted before the beforeunload
and unload
event of the DOM. Calling event.preventDefault()
will cancel the close.
Usually you would want to use the beforeunload
handler to decide whether the window should be closed, which will also be called when the window is reloaded. In Electron, returning any value other than undefined
would cancel the close. For example:
window.onbeforeunload = (e) => { console.log('I do not want to be closed') // Unlike usual browsers that a message box will be prompted to users, returning // a non-void value will silently cancel the close. // It is recommended to use the dialog API to let the user confirm closing the // application. e.returnValue = false // equivalent to `return false` but not recommended }
Note: There is a subtle difference between the behaviors of window.onbeforeunload = handler
and window.addEventListener('beforeunload', handler)
. It is recommended to always set the event.returnValue
explicitly, instead of only returning a value, as the former works more consistently within Electron.
Emitted when the window is closed. After you have received this event you should remove the reference to the window and avoid using it any more.
Emitted when window session is going to end due to force shutdown or machine restart or session log off.
Emitted when the web page becomes unresponsive.
Emitted when the unresponsive web page becomes responsive again.
Emitted when the window loses focus.
Emitted when the window gains focus.
Emitted when the window is shown.
Emitted when the window is hidden.
Emitted when the web page has been rendered (while not being shown) and window can be displayed without a visual flash.
Please note that using this event implies that the renderer will be considered "visible" and paint even though show
is false. This event will never fire if you use paintWhenInitiallyHidden: false
Emitted when window is maximized.
Emitted when the window exits from a maximized state.
Emitted when the window is minimized.
Emitted when the window is restored from a minimized state.
Returns:
event
EventnewBounds
Rectangle - Size the window is being resized to.Emitted before the window is resized. Calling event.preventDefault()
will prevent the window from being resized.
Note that this is only emitted when the window is being resized manually. Resizing the window with setBounds
/setSize
will not emit this event.
Emitted after the window has been resized.
Emitted once when the window has finished being resized.
This is usually emitted when the window has been resized manually. On macOS, resizing the window with setBounds
/setSize
and setting the animate
parameter to true
will also emit this event once resizing has finished.
Returns:
event
EventnewBounds
Rectangle - Location the window is being moved to.Emitted before the window is moved. On Windows, calling event.preventDefault()
will prevent the window from being moved.
Note that this is only emitted when the window is being resized manually. Resizing the window with setBounds
/setSize
will not emit this event.
Emitted when the window is being moved to a new position.
Emitted once when the window is moved to a new position.
Note: On macOS this event is an alias of move
.
Emitted when the window enters a full-screen state.
Emitted when the window leaves a full-screen state.
Emitted when the window enters a full-screen state triggered by HTML API.
Emitted when the window leaves a full-screen state triggered by HTML API.
Returns:
event
EventisAlwaysOnTop
BooleanEmitted when the window is set or unset to show always on top of other windows.
Returns:
event
Eventcommand
StringEmitted when an App Command is invoked. These are typically related to keyboard media keys or browser commands, as well as the "Back" button built into some mice on Windows.
Commands are lowercased, underscores are replaced with hyphens, and the APPCOMMAND_
prefix is stripped off. e.g. APPCOMMAND_BROWSER_BACKWARD
is emitted as browser-backward
.
const { BrowserWindow } = require('electron') const win = new BrowserWindow() win.on('app-command', (e, cmd) => { // Navigate the window back when the user hits their mouse back button if (cmd === 'browser-backward' && win.webContents.canGoBack()) { win.webContents.goBack() } })
The following app commands are explicitly supported on Linux:
browser-backward
browser-forward
Emitted when scroll wheel event phase has begun.
Emitted when scroll wheel event phase has ended.
Emitted when scroll wheel event phase filed upon reaching the edge of element.
Returns:
event
Eventdirection
StringEmitted on 3-finger swipe. Possible directions are up
, right
, down
, left
.
The method underlying this event is built to handle older macOS-style trackpad swiping, where the content on the screen doesn't move with the swipe. Most macOS trackpads are not configured to allow this kind of swiping anymore, so in order for it to emit properly the 'Swipe between pages' preference in System Preferences > Trackpad > More Gestures
must be set to 'Swipe with two or three fingers'.
Returns:
event
Eventrotation
FloatEmitted on trackpad rotation gesture. Continually emitted until rotation gesture is ended. The rotation
value on each emission is the angle in degrees rotated since the last emission. The last emitted event upon a rotation gesture will always be of value 0
. Counter-clockwise rotation values are positive, while clockwise ones are negative.
Emitted when the window opens a sheet.
Emitted when the window has closed a sheet.
Emitted when the native new tab button is clicked.
Returns:
event
Eventpoint
Point - The screen coordinates the context menu was triggered atEmitted when the system context menu is triggered on the window, this is normally only triggered when the user right clicks on the non-client area of your window. This is the window titlebar or any area you have declared as -webkit-app-region: drag
in a frameless window.
Calling event.preventDefault()
will prevent the menu from being displayed.
The BrowserWindow
class has the following static methods:
BrowserWindow.getAllWindows()
Returns BrowserWindow[]
- An array of all opened browser windows.
BrowserWindow.getFocusedWindow()
Returns BrowserWindow | null
- The window that is focused in this application, otherwise returns null
.
BrowserWindow.fromWebContents(webContents)
webContents
WebContents
Returns BrowserWindow | null
- The window that owns the given webContents
or null
if the contents are not owned by a window.
BrowserWindow.fromBrowserView(browserView)
browserView
BrowserView
Returns BrowserWindow | null
- The window that owns the given browserView
. If the given view is not attached to any window, returns null
.
BrowserWindow.fromId(id)
id
IntegerReturns BrowserWindow | null
- The window with the given id
.
BrowserWindow.addExtension(path)
Deprecated
path
StringAdds Chrome extension located at path
, and returns extension's name.
The method will also not return if the extension's manifest is missing or incomplete.
Note: This API cannot be called before the ready
event of the app
module is emitted.
Note: This method is deprecated. Instead, use ses.loadExtension(path)
.
BrowserWindow.removeExtension(name)
Deprecated
name
StringRemove a Chrome extension by name.
Note: This API cannot be called before the ready
event of the app
module is emitted.
Note: This method is deprecated. Instead, use ses.removeExtension(extension_id)
.
BrowserWindow.getExtensions()
Deprecated
Returns Record<String, ExtensionInfo>
- The keys are the extension names and each value is an Object containing name
and version
properties.
Note: This API cannot be called before the ready
event of the app
module is emitted.
Note: This method is deprecated. Instead, use ses.getAllExtensions()
.
BrowserWindow.addDevToolsExtension(path)
Deprecated
path
StringAdds DevTools extension located at path
, and returns extension's name.
The extension will be remembered so you only need to call this API once, this API is not for programming use. If you try to add an extension that has already been loaded, this method will not return and instead log a warning to the console.
The method will also not return if the extension's manifest is missing or incomplete.
Note: This API cannot be called before the ready
event of the app
module is emitted.
Note: This method is deprecated. Instead, use ses.loadExtension(path)
.
BrowserWindow.removeDevToolsExtension(name)
Deprecated
name
StringRemove a DevTools extension by name.
Note: This API cannot be called before the ready
event of the app
module is emitted.
Note: This method is deprecated. Instead, use ses.removeExtension(extension_id)
.
BrowserWindow.getDevToolsExtensions()
Deprecated
Returns Record<string, ExtensionInfo>
- The keys are the extension names and each value is an Object containing name
and version
properties.
To check if a DevTools extension is installed you can run the following:
const { BrowserWindow } = require('electron') const installed = 'devtron' in BrowserWindow.getDevToolsExtensions() console.log(installed)
Note: This API cannot be called before the ready
event of the app
module is emitted.
Note: This method is deprecated. Instead, use ses.getAllExtensions()
.
Objects created with new BrowserWindow
have the following properties:
const { BrowserWindow } = require('electron') // In this example `win` is our instance const win = new BrowserWindow({ width: 800, height: 600 }) win.loadURL('https://github.com')
win.webContents
Readonly
A WebContents
object this window owns. All web page related events and operations will be done via it.
See the webContents
documentation for its methods and events.
win.id
Readonly
A Integer
property representing the unique ID of the window. Each ID is unique among all BrowserWindow
instances of the entire Electron application.
win.autoHideMenuBar
A Boolean
property that determines whether the window menu bar should hide itself automatically. Once set, the menu bar will only show when users press the single Alt
key.
If the menu bar is already visible, setting this property to true
won't hide it immediately.
win.simpleFullScreen
A Boolean
property that determines whether the window is in simple (pre-Lion) fullscreen mode.
win.fullScreen
A Boolean
property that determines whether the window is in fullscreen mode.
win.visibleOnAllWorkspaces
A Boolean
property that determines whether the window is visible on all workspaces.
Note: Always returns false on Windows.
win.shadow
A Boolean
property that determines whether the window has a shadow.
win.menuBarVisible
Windows Linux
A Boolean
property that determines whether the menu bar should be visible.
Note: If the menu bar is auto-hide, users can still bring up the menu bar by pressing the single Alt
key.
win.kiosk
A Boolean
property that determines whether the window is in kiosk mode.
win.documentEdited
macOS
A Boolean
property that specifies whether the window’s document has been edited.
The icon in title bar will become gray when set to true
.
win.representedFilename
macOS
A String
property that determines the pathname of the file the window represents, and the icon of the file will show in window's title bar.
win.title
A String
property that determines the title of the native window.
Note: The title of the web page can be different from the title of the native window.
win.minimizable
A Boolean
property that determines whether the window can be manually minimized by user.
On Linux the setter is a no-op, although the getter returns true
.
win.maximizable
A Boolean
property that determines whether the window can be manually maximized by user.
On Linux the setter is a no-op, although the getter returns true
.
win.fullScreenable
A Boolean
property that determines whether the maximize/zoom window button toggles fullscreen mode or maximizes the window.
win.resizable
A Boolean
property that determines whether the window can be manually resized by user.
win.closable
A Boolean
property that determines whether the window can be manually closed by user.
On Linux the setter is a no-op, although the getter returns true
.
win.movable
A Boolean
property that determines Whether the window can be moved by user.
On Linux the setter is a no-op, although the getter returns true
.
win.excludedFromShownWindowsMenu
macOS
A Boolean
property that determines whether the window is excluded from the application’s Windows menu. false
by default.
const win = new BrowserWindow({ height: 600, width: 600 }) const template = [ { role: 'windowmenu' } ] win.excludedFromShownWindowsMenu = true const menu = Menu.buildFromTemplate(template) Menu.setApplicationMenu(menu)
win.accessibleTitle
A String
property that defines an alternative title provided only to accessibility tools such as screen readers. This string is not directly visible to users.
Objects created with new BrowserWindow
have the following instance methods:
Note: Some methods are only available on specific operating systems and are labeled as such.
win.destroy()
Force closing the window, the unload
and beforeunload
event won't be emitted for the web page, and close
event will also not be emitted for this window, but it guarantees the closed
event will be emitted.
win.close()
Try to close the window. This has the same effect as a user manually clicking the close button of the window. The web page may cancel the close though. See the close event.
win.focus()
Focuses on the window.
win.blur()
Removes focus from the window.
win.isFocused()
Returns Boolean
- Whether the window is focused.
win.isDestroyed()
Returns Boolean
- Whether the window is destroyed.
win.show()
Shows and gives focus to the window.
win.showInactive()
Shows the window but doesn't focus on it.
win.hide()
Hides the window.
win.isVisible()
Returns Boolean
- Whether the window is visible to the user.
win.isModal()
Returns Boolean
- Whether current window is a modal window.
win.maximize()
Maximizes the window. This will also show (but not focus) the window if it isn't being displayed already.
win.unmaximize()
Unmaximizes the window.
win.isMaximized()
Returns Boolean
- Whether the window is maximized.
win.minimize()
Minimizes the window. On some platforms the minimized window will be shown in the Dock.
win.restore()
Restores the window from minimized state to its previous state.
win.isMinimized()
Returns Boolean
- Whether the window is minimized.
win.setFullScreen(flag)
flag
BooleanSets whether the window should be in fullscreen mode.
win.isFullScreen()
Returns Boolean
- Whether the window is in fullscreen mode.
win.setSimpleFullScreen(flag)
macOS
flag
BooleanEnters or leaves simple fullscreen mode.
Simple fullscreen mode emulates the native fullscreen behavior found in versions of macOS prior to Lion (10.7).
win.isSimpleFullScreen()
macOS
Returns Boolean
- Whether the window is in simple (pre-Lion) fullscreen mode.
win.isNormal()
Returns Boolean
- Whether the window is in normal state (not maximized, not minimized, not in fullscreen mode).
win.setAspectRatio(aspectRatio[, extraSize])
macOS Linux
aspectRatio
Float - The aspect ratio to maintain for some portion of the content view.extraSize
Size (optional) macOS - The extra size not to be included while maintaining the aspect ratio.This will make a window maintain an aspect ratio. The extra size allows a developer to have space, specified in pixels, not included within the aspect ratio calculations. This API already takes into account the difference between a window's size and its content size.
Consider a normal window with an HD video player and associated controls. Perhaps there are 15 pixels of controls on the left edge, 25 pixels of controls on the right edge and 50 pixels of controls below the player. In order to maintain a 16:9 aspect ratio (standard aspect ratio for HD @1920x1080) within the player itself we would call this function with arguments of 16/9 and { width: 40, height: 50 }. The second argument doesn't care where the extra width and height are within the content view--only that they exist. Sum any extra width and height areas you have within the overall content view.
win.setBackgroundColor(backgroundColor)
backgroundColor
String - Window's background color as a hexadecimal value, like #66CD00
or #FFF
or #80FFFFFF
(alpha is supported if transparent
is true
). Default is #FFF
(white).Sets the background color of the window. See Setting backgroundColor
.
win.previewFile(path[, displayName])
macOS
path
String - The absolute path to the file to preview with QuickLook. This is important as Quick Look uses the file name and file extension on the path to determine the content type of the file to open.displayName
String (optional) - The name of the file to display on the Quick Look modal view. This is purely visual and does not affect the content type of the file. Defaults to path
.Uses Quick Look to preview a file at a given path.
win.closeFilePreview()
macOS
Closes the currently open Quick Look panel.
win.setBounds(bounds[, animate])
bounds
Partial<Rectangle>animate
Boolean (optional) macOS
Resizes and moves the window to the supplied bounds. Any properties that are not supplied will default to their current values.
const { BrowserWindow } = require('electron') const win = new BrowserWindow() // set all bounds properties win.setBounds({ x: 440, y: 225, width: 800, height: 600 }) // set a single bounds property win.setBounds({ width: 100 }) // { x: 440, y: 225, width: 100, height: 600 } console.log(win.getBounds())
win.getBounds()
Returns Rectangle
- The bounds
of the window as Object
.
win.getBackgroundColor()
Returns String
- Gets the background color of the window. See Setting backgroundColor
.
win.setContentBounds(bounds[, animate])
bounds
Rectangle
animate
Boolean (optional) macOS
Resizes and moves the window's client area (e.g. the web page) to the supplied bounds.
win.getContentBounds()
Returns Rectangle
- The bounds
of the window's client area as Object
.
win.getNormalBounds()
Returns Rectangle
- Contains the window bounds of the normal state
Note: whatever the current state of the window : maximized, minimized or in fullscreen, this function always returns the position and size of the window in normal state. In normal state, getBounds and getNormalBounds returns the same Rectangle
.
win.setEnabled(enable)
enable
BooleanDisable or enable the window.
win.isEnabled()
Returns Boolean
- whether the window is enabled.
win.setSize(width, height[, animate])
width
Integerheight
Integeranimate
Boolean (optional) macOS
Resizes the window to width
and height
. If width
or height
are below any set minimum size constraints the window will snap to its minimum size.
win.getSize()
Returns Integer[]
- Contains the window's width and height.
win.setContentSize(width, height[, animate])
width
Integerheight
Integeranimate
Boolean (optional) macOS
Resizes the window's client area (e.g. the web page) to width
and height
.
win.getContentSize()
Returns Integer[]
- Contains the window's client area's width and height.
win.setMinimumSize(width, height)
width
Integerheight
IntegerSets the minimum size of window to width
and height
.
win.getMinimumSize()
Returns Integer[]
- Contains the window's minimum width and height.
win.setMaximumSize(width, height)
width
Integerheight
IntegerSets the maximum size of window to width
and height
.
win.getMaximumSize()
Returns Integer[]
- Contains the window's maximum width and height.
win.setResizable(resizable)
resizable
BooleanSets whether the window can be manually resized by the user.
win.isResizable()
Returns Boolean
- Whether the window can be manually resized by the user.
win.setMovable(movable)
macOS Windows
movable
BooleanSets whether the window can be moved by user. On Linux does nothing.
win.isMovable()
macOS Windows
Returns Boolean
- Whether the window can be moved by user.
On Linux always returns true
.
win.setMinimizable(minimizable)
macOS Windows
minimizable
BooleanSets whether the window can be manually minimized by user. On Linux does nothing.
win.isMinimizable()
macOS Windows
Returns Boolean
- Whether the window can be manually minimized by the user.
On Linux always returns true
.
win.setMaximizable(maximizable)
macOS Windows
maximizable
BooleanSets whether the window can be manually maximized by user. On Linux does nothing.
win.isMaximizable()
macOS Windows
Returns Boolean
- Whether the window can be manually maximized by user.
On Linux always returns true
.
win.setFullScreenable(fullscreenable)
fullscreenable
BooleanSets whether the maximize/zoom window button toggles fullscreen mode or maximizes the window.
win.isFullScreenable()
Returns Boolean
- Whether the maximize/zoom window button toggles fullscreen mode or maximizes the window.
win.setClosable(closable)
macOS Windows
closable
BooleanSets whether the window can be manually closed by user. On Linux does nothing.
win.isClosable()
macOS Windows
Returns Boolean
- Whether the window can be manually closed by user.
On Linux always returns true
.
win.setAlwaysOnTop(flag[, level][, relativeLevel])
flag
Booleanlevel
String (optional) macOS Windows - Values include normal
, floating
, torn-off-menu
, modal-panel
, main-menu
, status
, pop-up-menu
, screen-saver
, and dock
floating
when flag
is true. The level
is reset to normal
when the flag is false. Note that from floating
to status
included, the window is placed below the Dock on macOS and below the taskbar on Windows. From pop-up-menu
to a higher it is shown above the Dock on macOS and above the taskbar on Windows. See the macOS docs for more details.relativeLevel
Integer (optional) macOS - The number of layers higher to set this window relative to the given level
. The default is 0
. Note that Apple discourages setting levels higher than 1 above screen-saver
.Sets whether the window should show always on top of other windows. After setting this, the window is still a normal window, not a toolbox window which can not be focused on.
win.isAlwaysOnTop()
Returns Boolean
- Whether the window is always on top of other windows.
win.moveAbove(mediaSourceId)
mediaSourceId
String - Window id in the format of DesktopCapturerSource's id. For example "window:1869:0".Moves window above the source window in the sense of z-order. If the mediaSourceId
is not of type window or if the window does not exist then this method throws an error.
win.moveTop()
Moves window to top(z-order) regardless of focus
win.center()
Moves window to the center of the screen.
win.setPosition(x, y[, animate])
x
Integery
Integeranimate
Boolean (optional) macOS
Moves window to x
and y
.
win.getPosition()
Returns Integer[]
- Contains the window's current position.
win.setTitle(title)
title
StringChanges the title of native window to title
.
win.getTitle()
Returns String
- The title of the native window.
Note: The title of the web page can be different from the title of the native window.
win.setSheetOffset(offsetY[, offsetX])
macOS
offsetY
FloatoffsetX
Float (optional)Changes the attachment point for sheets on macOS. By default, sheets are attached just below the window frame, but you may want to display them beneath a HTML-rendered toolbar. For example:
const { BrowserWindow } = require('electron') const win = new BrowserWindow() const toolbarRect = document.getElementById('toolbar').getBoundingClientRect() win.setSheetOffset(toolbarRect.height)
win.flashFrame(flag)
flag
BooleanStarts or stops flashing the window to attract user's attention.
win.setSkipTaskbar(skip)
skip
BooleanMakes the window not show in the taskbar.
win.setKiosk(flag)
flag
BooleanEnters or leaves kiosk mode.
win.isKiosk()
Returns Boolean
- Whether the window is in kiosk mode.
win.getMediaSourceId()
Returns String
- Window id in the format of DesktopCapturerSource's id. For example "window🔢0".
More precisely the format is window:id:other_id
where id
is HWND
on Windows, CGWindowID
(uint64_t
) on macOS and Window
(unsigned long
) on Linux. other_id
is used to identify web contents (tabs) so within the same top level window.
win.getNativeWindowHandle()
Returns Buffer
- The platform-specific handle of the window.
The native type of the handle is HWND
on Windows, NSView*
on macOS, and Window
(unsigned long
) on Linux.
win.hookWindowMessage(message, callback)
Windows
message
Integercallback
FunctionHooks a windows message. The callback
is called when the message is received in the WndProc.
win.isWindowMessageHooked(message)
Windows
message
IntegerReturns Boolean
- true
or false
depending on whether the message is hooked.
win.unhookWindowMessage(message)
Windows
message
IntegerUnhook the window message.
win.unhookAllWindowMessages()
Windows
Unhooks all of the window messages.
win.setRepresentedFilename(filename)
macOS
filename
StringSets the pathname of the file the window represents, and the icon of the file will show in window's title bar.
win.getRepresentedFilename()
macOS
Returns String
- The pathname of the file the window represents.
win.setDocumentEdited(edited)
macOS
edited
BooleanSpecifies whether the window’s document has been edited, and the icon in title bar will become gray when set to true
.
win.isDocumentEdited()
macOS
Returns Boolean
- Whether the window's document has been edited.
win.focusOnWebView()
win.blurWebView()
win.capturePage([rect])
rect
Rectangle (optional) - The bounds to captureReturns Promise<NativeImage>
- Resolves with a NativeImage
Captures a snapshot of the page within rect
. Omitting rect
will capture the whole visible page.
win.loadURL(url[, options])
url
Stringoptions
Object (optional)httpReferrer
(String | Referrer) (optional) - An HTTP Referrer URL.userAgent
String (optional) - A user agent originating the request.extraHeaders
String (optional) - Extra headers separated by "\n"postData
(UploadRawData[] | UploadFile[] | UploadBlob[]) (optional)baseURLForDataURL
String (optional) - Base URL (with trailing path separator) for files to be loaded by the data URL. This is needed only if the specified url
is a data URL and needs to load other files.Returns Promise<void>
- the promise will resolve when the page has finished loading (see did-finish-load
), and rejects if the page fails to load (see did-fail-load
).
Same as webContents.loadURL(url[, options])
.
The url
can be a remote address (e.g. http://
) or a path to a local HTML file using the file://
protocol.
To ensure that file URLs are properly formatted, it is recommended to use Node's url.format
method:
const url = require('url').format({ protocol: 'file', slashes: true, pathname: require('path').join(__dirname, 'index.html') }) win.loadURL(url)
You can load a URL using a POST
request with URL-encoded data by doing the following:
win.loadURL('http://localhost:8000/post', { postData: [{ type: 'rawData', bytes: Buffer.from('hello=world') }], extraHeaders: 'Content-Type: application/x-www-form-urlencoded' })
win.loadFile(filePath[, options])
filePath
Stringoptions
Object (optional)query
Record<String, String> (optional) - Passed to url.format()
.search
String (optional) - Passed to url.format()
.hash
String (optional) - Passed to url.format()
.Returns Promise<void>
- the promise will resolve when the page has finished loading (see did-finish-load
), and rejects if the page fails to load (see did-fail-load
).
Same as webContents.loadFile
, filePath
should be a path to an HTML file relative to the root of your application. See the webContents
docs for more information.
win.reload()
Same as webContents.reload
.
win.setMenu(menu)
Linux Windows
menu
Menu | nullSets the menu
as the window's menu bar.
win.removeMenu()
Linux Windows
Remove the window's menu bar.
win.setProgressBar(progress[, options])
progress
Doubleoptions
Object (optional)mode
String Windows - Mode for the progress bar. Can be none
, normal
, indeterminate
, error
or paused
.Sets progress value in progress bar. Valid range is [0, 1.0].
Remove progress bar when progress < 0; Change to indeterminate mode when progress > 1.
On Linux platform, only supports Unity desktop environment, you need to specify the *.desktop
file name to desktopName
field in package.json
. By default, it will assume {app.name}.desktop
.
On Windows, a mode can be passed. Accepted values are none
, normal
, indeterminate
, error
, and paused
. If you call setProgressBar
without a mode set (but with a value within the valid range), normal
will be assumed.
win.setOverlayIcon(overlay, description)
Windows
overlay
NativeImage | null - the icon to display on the bottom right corner of the taskbar icon. If this parameter is null
, the overlay is cleareddescription
String - a description that will be provided to Accessibility screen readersSets a 16 x 16 pixel overlay onto the current taskbar icon, usually used to convey some sort of application status or to passively notify the user.
win.setHasShadow(hasShadow)
hasShadow
BooleanSets whether the window should have a shadow.
win.hasShadow()
Returns Boolean
- Whether the window has a shadow.
win.setOpacity(opacity)
Windows macOS
opacity
Number - between 0.0 (fully transparent) and 1.0 (fully opaque)Sets the opacity of the window. On Linux, does nothing. Out of bound number values are clamped to the [0, 1] range.
win.getOpacity()
Returns Number
- between 0.0 (fully transparent) and 1.0 (fully opaque). On Linux, always returns 1.
win.setShape(rects)
Windows Linux Experimental
rects
Rectangle[] - Sets a shape on the window. Passing an empty list reverts the window to being rectangular.Setting a window shape determines the area within the window where the system permits drawing and user interaction. Outside of the given region, no pixels will be drawn and no mouse events will be registered. Mouse events outside of the region will not be received by that window, but will fall through to whatever is behind the window.
win.setThumbarButtons(buttons)
Windows
buttons
ThumbarButton[]
Returns Boolean
- Whether the buttons were added successfully
Add a thumbnail toolbar with a specified set of buttons to the thumbnail image of a window in a taskbar button layout. Returns a Boolean
object indicates whether the thumbnail has been added successfully.
The number of buttons in thumbnail toolbar should be no greater than 7 due to the limited room. Once you setup the thumbnail toolbar, the toolbar cannot be removed due to the platform's limitation. But you can call the API with an empty array to clean the buttons.
The buttons
is an array of Button
objects:
Button
Objecticon
NativeImage - The icon showing in thumbnail toolbar.click
Functiontooltip
String (optional) - The text of the button's tooltip.flags
String[] (optional) - Control specific states and behaviors of the button. By default, it is ['enabled']
.The flags
is an array that can include following String
s:
enabled
- The button is active and available to the user.disabled
- The button is disabled. It is present, but has a visual state indicating it will not respond to user action.dismissonclick
- When the button is clicked, the thumbnail window closes immediately.nobackground
- Do not draw a button border, use only the image.hidden
- The button is not shown to the user.noninteractive
- The button is enabled but not interactive; no pressed button state is drawn. This value is intended for instances where the button is used in a notification.win.setThumbnailClip(region)
Windows
region
Rectangle - Region of the windowSets the region of the window to show as the thumbnail image displayed when hovering over the window in the taskbar. You can reset the thumbnail to be the entire window by specifying an empty region: { x: 0, y: 0, width: 0, height: 0 }
.
win.setThumbnailToolTip(toolTip)
Windows
toolTip
StringSets the toolTip that is displayed when hovering over the window thumbnail in the taskbar.
win.setAppDetails(options)
Windows
options
ObjectappId
String (optional) - Window's App User Model ID. It has to be set, otherwise the other options will have no effect.appIconPath
String (optional) - Window's Relaunch Icon.appIconIndex
Integer (optional) - Index of the icon in appIconPath
. Ignored when appIconPath
is not set. Default is 0
.relaunchCommand
String (optional) - Window's Relaunch Command.relaunchDisplayName
String (optional) - Window's Relaunch Display Name.Sets the properties for the window's taskbar button.
Note: relaunchCommand
and relaunchDisplayName
must always be set together. If one of those properties is not set, then neither will be used.
win.showDefinitionForSelection()
macOS
Same as webContents.showDefinitionForSelection()
.
win.setIcon(icon)
Windows Linux
icon
NativeImage | StringChanges window icon.
win.setWindowButtonVisibility(visible)
macOS
visible
BooleanSets whether the window traffic light buttons should be visible.
This cannot be called when titleBarStyle
is set to customButtonsOnHover
.
win.setAutoHideMenuBar(hide)
hide
BooleanSets whether the window menu bar should hide itself automatically. Once set the menu bar will only show when users press the single Alt
key.
If the menu bar is already visible, calling setAutoHideMenuBar(true)
won't hide it immediately.
win.isMenuBarAutoHide()
Returns Boolean
- Whether menu bar automatically hides itself.
win.setMenuBarVisibility(visible)
Windows Linux
visible
BooleanSets whether the menu bar should be visible. If the menu bar is auto-hide, users can still bring up the menu bar by pressing the single Alt
key.
win.isMenuBarVisible()
Returns Boolean
- Whether the menu bar is visible.
win.setVisibleOnAllWorkspaces(visible[, options])
visible
Booleanoptions
Object (optional)visibleOnFullScreen
Boolean (optional) macOS - Sets whether the window should be visible above fullscreen windowsSets whether the window should be visible on all workspaces.
Note: This API does nothing on Windows.
win.isVisibleOnAllWorkspaces()
Returns Boolean
- Whether the window is visible on all workspaces.
Note: This API always returns false on Windows.
win.setIgnoreMouseEvents(ignore[, options])
ignore
Booleanoptions
Object (optional)forward
Boolean (optional) macOS Windows - If true, forwards mouse move messages to Chromium, enabling mouse related events such as mouseleave
. Only used when ignore
is true. If ignore
is false, forwarding is always disabled regardless of this value.Makes the window ignore all mouse events.
All mouse events happened in this window will be passed to the window below this window, but if this window has focus, it will still receive keyboard events.
win.setContentProtection(enable)
macOS Windows
enable
BooleanPrevents the window contents from being captured by other apps.
On macOS it sets the NSWindow's sharingType to NSWindowSharingNone. On Windows it calls SetWindowDisplayAffinity with WDA_MONITOR
.
win.setFocusable(focusable)
macOS Windows
focusable
BooleanChanges whether the window can be focused.
On macOS it does not remove the focus from the window.
win.setParentWindow(parent)
parent
BrowserWindow | nullSets parent
as current window's parent window, passing null
will turn current window into a top-level window.
win.getParentWindow()
Returns BrowserWindow
- The parent window.
win.getChildWindows()
Returns BrowserWindow[]
- All child windows.
win.setAutoHideCursor(autoHide)
macOS
autoHide
BooleanControls whether to hide cursor when typing.
win.selectPreviousTab()
macOS
Selects the previous tab when native tabs are enabled and there are other tabs in the window.
win.selectNextTab()
macOS
Selects the next tab when native tabs are enabled and there are other tabs in the window.
win.mergeAllWindows()
macOS
Merges all windows into one window with multiple tabs when native tabs are enabled and there is more than one open window.
win.moveTabToNewWindow()
macOS
Moves the current tab into a new window if native tabs are enabled and there is more than one tab in the current window.
win.toggleTabBar()
macOS
Toggles the visibility of the tab bar if native tabs are enabled and there is only one tab in the current window.
win.addTabbedWindow(browserWindow)
macOS
browserWindow
BrowserWindowAdds a window as a tab on this window, after the tab for the window instance.
win.setVibrancy(type)
macOS
type
String | null - Can be appearance-based
, light
, dark
, titlebar
, selection
, menu
, popover
, sidebar
, medium-light
, ultra-dark
, header
, sheet
, window
, hud
, fullscreen-ui
, tooltip
, content
, under-window
, or under-page
. See the macOS documentation for more details.Adds a vibrancy effect to the browser window. Passing null
or an empty string will remove the vibrancy effect on the window.
Note that appearance-based
, light
, dark
, medium-light
, and ultra-dark
have been deprecated and will be removed in an upcoming version of macOS.
win.setTrafficLightPosition(position)
macOS
position
Point
Set a custom position for the traffic light buttons. Can only be used with titleBarStyle
set to hidden
.
win.getTrafficLightPosition()
macOS
Returns Point
- The current position for the traffic light buttons. Can only be used with titleBarStyle
set to hidden
.
win.setTouchBar(touchBar)
macOS
touchBar
TouchBar | nullSets the touchBar layout for the current window. Specifying null
or undefined
clears the touch bar. This method only has an effect if the machine has a touch bar and is running on macOS 10.12.1+.
Note: The TouchBar API is currently experimental and may change or be removed in future Electron releases.
win.setBrowserView(browserView)
Experimental
browserView
BrowserView | null - Attach browserView
to win
. If there are other BrowserView
s attached, they will be removed from this window.win.getBrowserView()
Experimental
Returns BrowserView | null
- The BrowserView
attached to win
. Returns null
if one is not attached. Throws an error if multiple BrowserView
s are attached.
win.addBrowserView(browserView)
Experimental
browserView
BrowserView
Replacement API for setBrowserView supporting work with multi browser views.
win.removeBrowserView(browserView)
Experimental
browserView
BrowserView
win.getBrowserViews()
Experimental
Returns BrowserView[]
- an array of all BrowserViews that have been attached with addBrowserView
or setBrowserView
.
Note: The BrowserView API is currently experimental and may change or be removed in future Electron releases.
Manipulate the child browser window
Process: Renderer
The BrowserWindowProxy
object is returned from window.open
and provides limited functionality with the child window.
The BrowserWindowProxy
object has the following instance methods:
win.blur()
Removes focus from the child window.
win.close()
Forcefully closes the child window without calling its unload event.
win.eval(code)
code
StringEvaluates the code in the child window.
win.focus()
Focuses the child window (brings the window to front).
win.print()
Invokes the print dialog on the child window.
win.postMessage(message, targetOrigin)
message
anytargetOrigin
StringSends a message to the child window with the specified origin or *
for no origin preference.
In addition to these methods, the child window implements window.opener
object with no properties and a single method.
The BrowserWindowProxy
object has the following instance properties:
win.closed
A Boolean
that is set to true after the child window gets closed.
Follow the guidelines below for building Electron.
Check the build prerequisites for your platform before proceeding
Electron's Build Tools automate much of the setup for compiling Electron from source with different configurations and build targets. If you wish to set up the environment manually, the instructions are listed below.
You'll need to install depot_tools
, the toolset used for fetching Chromium and its dependencies.
Also, on Windows, you'll need to set the environment variable DEPOT_TOOLS_WIN_TOOLCHAIN=0
. To do so, open Control Panel
→ System and Security
→ System
→ Advanced system settings
and add a system variable DEPOT_TOOLS_WIN_TOOLCHAIN
with value 0
. This tells depot_tools
to use your locally installed version of Visual Studio (by default, depot_tools
will try to download a Google-internal version that only Googlers have access to).
If you plan on checking out Electron more than once (for example, to have multiple parallel directories checked out to different branches), using the git cache will speed up subsequent calls to gclient
. To do this, set a GIT_CACHE_PATH
environment variable:
$ export GIT_CACHE_PATH="${HOME}/.git_cache" $ mkdir -p "${GIT_CACHE_PATH}" # This will use about 16G.
$ mkdir electron && cd electron $ gclient config --name "src/electron" --unmanaged https://github.com/electron/electron $ gclient sync --with_branch_heads --with_tags # This will take a while, go get a coffee.
Instead of
https://github.com/electron/electron
, you can use your own fork here (something likehttps://github.com/<username>/electron
).
If you intend to git pull
or git push
from the official electron
repository in the future, you now need to update the respective folder's origin URLs.
$ cd src/electron $ git remote remove origin $ git remote add origin https://github.com/electron/electron $ git checkout master $ git branch --set-upstream-to=origin/master $ cd -
📝 gclient
works by checking a file called DEPS
inside the src/electron
folder for dependencies (like Chromium or Node.js). Running gclient sync -f
ensures that all dependencies required to build Electron match that file.
So, in order to pull, you'd run the following commands:
$ cd src/electron $ git pull $ gclient sync -f
$ cd src $ export CHROMIUM_BUILDTOOLS_PATH=`pwd`/buildtools # this next line is needed only if building with sccache $ export GN_EXTRA_ARGS="${GN_EXTRA_ARGS} cc_wrapper=\"${PWD}/electron/external_binaries/sccache\"" $ gn gen out/Testing --args="import(\"//electron/build/args/testing.gn\") $GN_EXTRA_ARGS"
Or on Windows (without the optional argument):
$ cd src $ set CHROMIUM_BUILDTOOLS_PATH=%cd%\buildtools $ gn gen out/Testing --args="import(\"//electron/build/args/testing.gn\")"
This will generate a build directory out/Testing
under src/
with the testing build configuration. You can replace Testing
with another name, but it should be a subdirectory of out
. Also you shouldn't have to run gn gen
again—if you want to change the build arguments, you can run gn args out/Testing
to bring up an editor.
To see the list of available build configuration options, run gn args out/Testing --list
.
For generating Testing build config of Electron:
$ gn gen out/Testing --args="import(\"//electron/build/args/testing.gn\") $GN_EXTRA_ARGS"
For generating Release (aka "non-component" or "static") build config of Electron:
$ gn gen out/Release --args="import(\"//electron/build/args/release.gn\") $GN_EXTRA_ARGS"
To build, run ninja
with the electron
target: Nota Bene: This will also take a while and probably heat up your lap.
For the testing configuration:
$ ninja -C out/Testing electron
For the release configuration:
$ ninja -C out/Release electron
This will build all of what was previously 'libchromiumcontent' (i.e. the content/
directory of chromium
and its dependencies, incl. WebKit and V8), so it will take a while.
To speed up subsequent builds, you can use sccache. Add the GN arg cc_wrapper = "sccache"
by running gn args out/Testing
to bring up an editor and adding a line to the end of the file.
The built executable will be under ./out/Testing
:
$ ./out/Testing/Electron.app/Contents/MacOS/Electron # or, on Windows $ ./out/Testing/electron.exe # or, on Linux $ ./out/Testing/electron
On linux, first strip the debugging and symbol information:
electron/script/strip-binaries.py -d out/Release
To package the electron build as a distributable zip file:
ninja -C out/Release electron:electron_dist_zip
To compile for a platform that isn't the same as the one you're building on, set the target_cpu
and target_os
GN arguments. For example, to compile an x86 target from an x64 host, specify target_cpu = "x86"
in gn args
.
$ gn gen out/Testing-x86 --args='... target_cpu = "x86"'
Not all combinations of source and target CPU/OS are supported by Chromium.
Host | Target | Status |
---|---|---|
Windows x64 | Windows arm64 | Experimental |
Windows x64 | Windows x86 | Automatically tested |
Linux x64 | Linux x86 | Automatically tested |
If you test other combinations and find them to work, please update this document :)
See the GN reference for allowable values of target_os
and target_cpu
.
To cross-compile for Windows on Arm, follow Chromium's guide to get the necessary dependencies, SDK and libraries, then build with ELECTRON_BUILDING_WOA=1
in your environment before running gclient sync
.
set ELECTRON_BUILDING_WOA=1 gclient sync -f --with_branch_heads --with_tags
Or (if using PowerShell):
$env:ELECTRON_BUILDING_WOA=1 gclient sync -f --with_branch_heads --with_tags
Next, run gn gen
as above with target_cpu="arm64"
.
To run the tests, you'll first need to build the test modules against the same version of Node.js that was built as part of the build process. To generate build headers for the modules to compile against, run the following under src/
directory.
$ ninja -C out/Testing third_party/electron_node:headers
You can now run the tests.
If you're debugging something, it can be helpful to pass some extra flags to the Electron binary:
$ npm run test -- \ --enable-logging -g 'BrowserWindow module'
It is possible to share the gclient git cache with other machines by exporting it as SMB share on linux, but only one process/machine can be using the cache at a time. The locks created by git-cache script will try to prevent this, but it may not work perfectly in a network.
On Windows, SMBv2 has a directory cache that will cause problems with the git cache script, so it is necessary to disable it by setting the registry key
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Lanmanworkstation\Parameters\DirectoryCacheLifetime
to 0. More information: https://stackoverflow.com/a/9935126
This can be set quickly in powershell (ran as administrator):
New-ItemProperty -Path "HKLM:\System\CurrentControlSet\Services\Lanmanworkstation\Parameters" -Name DirectoryCacheLifetime -Value 0 -PropertyType DWORD -Force
If gclient sync
is interrupted the git tree may be left in a bad state, leading to a cryptic message when running gclient sync
in the future:
2> Conflict while rebasing this branch. 2> Fix the conflict and run gclient again. 2> See man git-rebase for details.
If there are no git conflicts or rebases in src/electron
, you may need to abort a git am
in src
:
$ cd ../ $ git am --abort $ cd electron $ gclient sync -f
If you see a prompt for Username for 'https://chrome-internal.googlesource.com':
when running gclient sync
on Windows, it's probably because the DEPOT_TOOLS_WIN_TOOLCHAIN
environment variable is not set to 0. Open Control Panel
→ System and Security
→ System
→ Advanced system settings
and add a system variable DEPOT_TOOLS_WIN_TOOLCHAIN
with value 0
. This tells depot_tools
to use your locally installed version of Visual Studio (by default, depot_tools
will try to download a Google-internal version that only Googlers have access to).
Follow the guidelines below for building Electron on Linux.
At least 25GB disk space and 8GB RAM.
Python 2.7.x. Some distributions like CentOS 6.x still use Python 2.6.x so you may need to check your Python version with python -V
.
Please also ensure that your system and Python version support at least TLS 1.2. For a quick test, run the following script:
$ npx @electron/check-python-tls
If the script returns that your configuration is using an outdated security protocol, use your system's package manager to update Python to the latest version in the 2.7.x branch. Alternatively, visit https://www.python.org/downloads/ for detailed instructions.
Node.js. There are various ways to install Node. You can download source code from nodejs.org and compile it. Doing so permits installing Node on your own home directory as a standard user. Or try repositories such as NodeSource.
clang 3.4 or later.
Development headers of GTK 3 and libnotify.
On Ubuntu, install the following libraries:
$ sudo apt-get install build-essential clang libdbus-1-dev libgtk-3-dev \ libnotify-dev libgnome-keyring-dev \ libasound2-dev libcap-dev libcups2-dev libxtst-dev \ libxss1 libnss3-dev gcc-multilib g++-multilib curl \ gperf bison python-dbusmock openjdk-8-jre
On RHEL / CentOS, install the following libraries:
$ sudo yum install clang dbus-devel gtk3-devel libnotify-devel \ libgnome-keyring-devel xorg-x11-server-utils libcap-devel \ cups-devel libXtst-devel alsa-lib-devel libXrandr-devel \ nss-devel python-dbusmock openjdk-8-jre
On Fedora, install the following libraries:
$ sudo dnf install clang dbus-devel gtk3-devel libnotify-devel \ libgnome-keyring-devel xorg-x11-server-utils libcap-devel \ cups-devel libXtst-devel alsa-lib-devel libXrandr-devel \ nss-devel python-dbusmock openjdk-8-jre
Other distributions may offer similar packages for installation via package managers such as pacman. Or one can compile from source code.
If you want to build for an arm
target you should also install the following dependencies:
$ sudo apt-get install libc6-dev-armhf-cross linux-libc-dev-armhf-cross \ g++-arm-linux-gnueabihf
Similarly for arm64
, install the following:
$ sudo apt-get install libc6-dev-arm64-cross linux-libc-dev-arm64-cross \ g++-aarch64-linux-gnu
And to cross-compile for arm
or ia32
targets, you should pass the target_cpu
parameter to gn gen
:
$ gn gen out/Testing --args='import(...) target_cpu="arm"'
Prebuilt clang
will try to link to libtinfo.so.5
. Depending on the host architecture, symlink to appropriate libncurses
:
$ sudo ln -s /usr/lib/libncurses.so.5 /usr/lib/libtinfo.so.5
The default building configuration is targeted for major desktop Linux distributions. To build for a specific distribution or device, the following information may help you.
clang
instead of downloaded clang
binariesBy default Electron is built with prebuilt clang
binaries provided by the Chromium project. If for some reason you want to build with the clang
installed in your system, you can specify the clang_base_path
argument in the GN args.
For example if you installed clang
under /usr/local/bin/clang
:
$ gn gen out/Testing --args='import("//electron/build/args/testing.gn") clang_base_path = "/usr/local/bin"'
clang
Building Electron with compilers other than clang
is not supported.
Follow the guidelines below for building Electron on macOS.
Please also ensure that your system and Python version support at least TLS 1.2. This depends on both your version of macOS and Python. For a quick test, run:
$ npx @electron/check-python-tls
If the script returns that your configuration is using an outdated security protocol, you can either update macOS to High Sierra or install a new version of Python 2.7.x. To upgrade Python, use Homebrew:
$ brew install [email protected] && brew link [email protected] --force
If you are using Python as provided by Homebrew, you also need to install the following Python modules:
You can use pip
to install it:
$ pip install pyobjc
If you're developing Electron and don't plan to redistribute your custom Electron build, you may skip this section.
Official Electron builds are built with Xcode 9.4.1, and the macOS 10.13 SDK. Building with a newer SDK works too, but the releases currently use the 10.13 SDK.
Follow the guidelines below for building Electron on Windows.
vs2019_install = DRIVE:\path\to\Microsoft Visual Studio\2019\Community
, replacing 2019
and Community
with your installed versions and replacing DRIVE:
with the drive that Visual Studio is on. Often, this will be C:
.WINDOWSSDKDIR = DRIVE:\path\to\Windows Kits\10
, replacing DRIVE:
with the drive that Windows Kits is on. Often, this will be C:
.symstore.exe
is used for creating a symbol store from .pdb
files.Change
→ Individual Components
, scroll down and select the appropriate Windows SDK to install. Another option would be to look at the Windows SDK and emulator archive and download the standalone version of the SDK respectively.Control Panel
→ Programs
→ Programs and Features
→ Select the "Windows Software Development Kit" → Change
→ Change
→ Check "Debugging Tools For Windows" → Change
. Or, you can download the standalone SDK installer and use it to install the Debugging Tools.If you don't currently have a Windows installation, dev.microsoftedge.com has timebombed versions of Windows that you can use to build Electron.
Building Electron is done entirely with command-line scripts and cannot be done with Visual Studio. You can develop Electron with any editor but support for building with Visual Studio will come in the future.
Note: Even though Visual Studio is not used for building, it's still required because we need the build toolchains it provides.
Windows Security doesn't like one of the files in the Chromium source code (see https://crbug.com/441184), so it will constantly delete it, causing gclient sync
issues. You can exclude the source tree from being monitored by Windows Security by following these instructions.
To build for the 32bit target, you need to pass target_cpu = "x86"
as a GN arg. You can build the 32bit target alongside the 64bit target by using a different output directory for GN, e.g. out/Release-x86
, with different arguments.
$ gn gen out/Release-x86 --args="import(\"//electron/build/args/release.gn\") target_cpu=\"x86\""
The other building steps are exactly the same.
To generate a Visual Studio project, you can pass the --ide=vs2017
parameter to gn gen
:
$ gn gen out/Testing --ide=vs2017
If you encountered an error like Command xxxx not found
, you may try to use the VS2015 Command Prompt
console to execute the build scripts.
Make sure you have the latest Visual Studio update installed.
Try reinstalling 32bit Node.js.
Creating that directory should fix the problem:
$ mkdir ~\AppData\Roaming\npm
You may get this error if you are using Git Bash for building, you should use PowerShell or VS2015 Command Prompt instead.
node.js has some extremely long pathnames, and by default git on windows doesn't handle long pathnames correctly (even though windows supports them). This should fix it:
$ git config --system core.longpaths true
This can happen during build, when Debugging Tools for Windows has been installed with Windows Driver Kit. Uninstall Windows Driver Kit and install Debugging Tools with steps described above.
Make sure you have installed pywin32
with pip install pywin32
.
This bug is a "feature" of Windows' command prompt. It happens when clicking inside the prompt window with QuickEdit
enabled and is intended to allow selecting and copying output text easily. Since each accidental click will pause the build process, you might want to disable this feature in the command prompt properties.
Electron uses GN for project generation and ninja for building. Project configurations can be found in the .gn
and .gni
files.
The following gn
files contain the main rules for building Electron:
BUILD.gn
defines how Electron itself is built and includes the default configurations for linking with Chromium.build/args/{debug,release,all}.gn
contain the default build arguments for building Electron.Since Chromium is quite a large project, the final linking stage can take quite a few minutes, which makes it hard for development. In order to solve this, Chromium introduced the "component build", which builds each component as a separate shared library, making linking very quick but sacrificing file size and performance.
Electron inherits this build option from Chromium. In Debug
builds, the binary will be linked to a shared library version of Chromium's components to achieve fast linking time; for Release
builds, the binary will be linked to the static library versions, so we can have the best possible binary size and performance.
NB this section is out of date and contains information that is no longer relevant to the GN-built electron.
Test your changes conform to the project coding style using:
$ npm run lint
Test functionality using:
$ npm test
Whenever you make changes to Electron source code, you'll need to re-run the build before the tests:
$ npm run build && npm test
You can make the test suite run faster by isolating the specific test or block you're currently working on using Mocha's exclusive tests feature. Append .only
to any describe
or it
function call:
describe.only('some feature', () => { // ... only tests in this block will be run })
Alternatively, you can use mocha's grep
option to only run tests matching the given regular expression pattern:
$ npm test -- --grep child_process
Tests that include native modules (e.g. runas
) can't be executed with the debug build (see #2558 for details), but they will work with the release build.
To run the tests with the release build use:
$ npm test -- -R
data
String - PEM encoded dataissuer
CertificatePrincipal - Issuer principalissuerName
String - Issuer's Common NameissuerCert
Certificate - Issuer certificate (if not self-signed)subject
CertificatePrincipal - Subject principalsubjectName
String - Subject's Common NameserialNumber
String - Hex value represented stringvalidStart
Number - Start date of the certificate being valid in secondsvalidExpiry
Number - End date of the certificate being valid in secondsfingerprint
String - Fingerprint of the certificatecommonName
String - Common Name.organizations
String[] - Organization names.organizationUnits
String[] - Organization Unit names.locality
String - Locality.state
String - State or province.country
String - Country or region.A collection of resources for learning about Chromium and tracking its development
See also V8 Development
clang-format
is a tool to automatically format C/C++/Objective-C code, so that developers don't need to worry about style issues during code reviews.
It is highly recommended to format your changed C++ code before opening pull requests, which will save you and the reviewers' time.
You can install clang-format
and git-clang-format
via npm install -g clang-format
.
To automatically format a file according to Electron C++ code style, run clang-format -i path/to/electron/file.cc
. It should work on macOS/Linux/Windows.
The workflow to format your changed code:
git add your_changed_file.cc
.git-clang-format
, and you will probably see modifications in your_changed_file.cc
, these modifications are generated from clang-format
.git add your_changed_file.cc
, and commit your change.If you want to format the changed code on your latest git commit (HEAD), you can run git-clang-format HEAD~1
. See git-clang-format -h
for more details.
You can also integrate clang-format
directly into your favorite editors. For further guidance on setting up editor integration, see these pages:
clang-tidy
is a tool to automatically check C/C++/Objective-C code for style violations, programming errors, and best practices.
Electron's clang-tidy
integration is provided as a linter script which can be run with npm run lint:clang-tidy
. While clang-tidy
checks your on-disk files, you need to have built Electron so that it knows which compiler flags were used. There is one required option for the script --output-dir
, which tells the script which build directory to pull the compilation information from. A typical usage would be: npm run lint:clang-tiy --out-dir ../out/Testing
With no filenames provided, all C/C++/Objective-C files will be checked. You can provide a list of files to be checked by passing the filenames after the options: npm run lint:clang-tiy --out-dir ../out/Testing shell/browser/api/electron_api_app.cc
While clang-tidy
has a long list of possible checks, in Electron only a few are enabled by default. At the moment Electron doesn't have a .clang-tidy
config, so clang-tidy
will find the one from Chromium at src/.clang-tidy
and use the checks which Chromium has enabled. You can change which checks are run by using the --checks=
option. This is passed straight through to clang-tidy
, so see its documentation for full details. Wildcards can be used, and checks can be disabled by prefixing a -
. By default any checks listed are added to those in .clang-tidy
, so if you'd like to limit the checks to specific ones you should first exclude all checks then add back what you want, like --checks=-*,performance*
.
Running clang-tidy
is rather slow - internally it compiles each file and then runs the checks so it will always be some factor slower than compilation. While you can use parallel runs to speed it up using the --jobs|-j
option, clang-tidy
also uses a lot of memory during its checks, so it can easily run into out-of-memory errors. As such the default number of jobs is one.
Make HTTP/HTTPS requests.
Process: Main
ClientRequest
implements the Writable Stream interface and is therefore an EventEmitter.
new ClientRequest(options)
options
(Object | String) - If options
is a String, it is interpreted as the request URL. If it is an object, it is expected to fully specify an HTTP request via the following properties:method
String (optional) - The HTTP request method. Defaults to the GET method.url
String (optional) - The request URL. Must be provided in the absolute form with the protocol scheme specified as http or https.session
Session (optional) - The Session
instance with which the request is associated.partition
String (optional) - The name of the partition
with which the request is associated. Defaults to the empty string. The session
option prevails on partition
. Thus if a session
is explicitly specified, partition
is ignored.useSessionCookies
Boolean (optional) - Whether to send cookies with this request from the provided session. This will make the net
request's cookie behavior match a fetch
request. Default is false
.protocol
String (optional) - The protocol scheme in the form 'scheme:'. Currently supported values are 'http:' or 'https:'. Defaults to 'http:'.host
String (optional) - The server host provided as a concatenation of the hostname and the port number 'hostname:port'.hostname
String (optional) - The server host name.port
Integer (optional) - The server's listening port number.path
String (optional) - The path part of the request URL.redirect
String (optional) - The redirect mode for this request. Should be one of follow
, error
or manual
. Defaults to follow
. When mode is error
, any redirection will be aborted. When mode is manual
the redirection will be cancelled unless request.followRedirect
is invoked synchronously during the redirect
event.options
properties such as protocol
, host
, hostname
, port
and path
strictly follow the Node.js model as described in the URL module.
For instance, we could have created the same request to 'github.com' as follows:
const request = net.request({ method: 'GET', protocol: 'https:', hostname: 'github.com', port: 443, path: '/' })
Returns:
response
IncomingMessage - An object representing the HTTP response message.Returns:
authInfo
ObjectisProxy
Booleanscheme
Stringhost
Stringport
Integerrealm
Stringcallback
Functionusername
String (optional)password
String (optional)Emitted when an authenticating proxy is asking for user credentials.
The callback
function is expected to be called back with user credentials:
username
Stringpassword
Stringrequest.on('login', (authInfo, callback) => { callback('username', 'password') })
Providing empty credentials will cancel the request and report an authentication error on the response object:
request.on('response', (response) => { console.log(`STATUS: ${response.statusCode}`); response.on('error', (error) => { console.log(`ERROR: ${JSON.stringify(error)}`) }) }) request.on('login', (authInfo, callback) => { callback() })
Emitted just after the last chunk of the request
's data has been written into the request
object.
Emitted when the request
is aborted. The abort
event will not be fired if the request
is already closed.
Returns:
error
Error - an error object providing some information about the failure.Emitted when the net
module fails to issue a network request. Typically when the request
object emits an error
event, a close
event will subsequently follow and no response object will be provided.
Emitted as the last event in the HTTP request-response transaction. The close
event indicates that no more events will be emitted on either the request
or response
objects.
Returns:
statusCode
Integermethod
StringredirectUrl
StringresponseHeaders
Record<String, String[]>Emitted when the server returns a redirect response (e.g. 301 Moved Permanently). Calling request.followRedirect
will continue with the redirection. If this event is handled, request.followRedirect
must be called synchronously, otherwise the request will be cancelled.
request.chunkedEncoding
A Boolean
specifying whether the request will use HTTP chunked transfer encoding or not. Defaults to false. The property is readable and writable, however it can be set only before the first write operation as the HTTP headers are not yet put on the wire. Trying to set the chunkedEncoding
property after the first write will throw an error.
Using chunked encoding is strongly recommended if you need to send a large request body as data will be streamed in small chunks instead of being internally buffered inside Electron process memory.
request.setHeader(name, value)
name
String - An extra HTTP header name.value
String - An extra HTTP header value.Adds an extra HTTP header. The header name will be issued as-is without lowercasing. It can be called only before first write. Calling this method after the first write will throw an error. If the passed value is not a String
, its toString()
method will be called to obtain the final value.
Certain headers are restricted from being set by apps. These headers are listed below. More information on restricted headers can be found in Chromium's header utils.
Content-Length
Host
Trailer
or Te
Upgrade
Cookie2
Keep-Alive
Transfer-Encoding
Additionally, setting the Connection
header to the value upgrade
is also disallowed.
request.getHeader(name)
name
String - Specify an extra header name.Returns String
- The value of a previously set extra header name.
request.removeHeader(name)
name
String - Specify an extra header name.Removes a previously set extra header name. This method can be called only before first write. Trying to call it after the first write will throw an error.
request.write(chunk[, encoding][, callback])
chunk
(String | Buffer) - A chunk of the request body's data. If it is a string, it is converted into a Buffer using the specified encoding.encoding
String (optional) - Used to convert string chunks into Buffer objects. Defaults to 'utf-8'.callback
Function (optional) - Called after the write operation ends.callback
is essentially a dummy function introduced in the purpose of keeping similarity with the Node.js API. It is called asynchronously in the next tick after chunk
content have been delivered to the Chromium networking layer. Contrary to the Node.js implementation, it is not guaranteed that chunk
content have been flushed on the wire before callback
is called.
Adds a chunk of data to the request body. The first write operation may cause the request headers to be issued on the wire. After the first write operation, it is not allowed to add or remove a custom header.
request.end([chunk][, encoding][, callback])
chunk
(String | Buffer) (optional)encoding
String (optional)callback
Function (optional)Sends the last chunk of the request data. Subsequent write or end operations will not be allowed. The finish
event is emitted just after the end operation.
request.abort()
Cancels an ongoing HTTP transaction. If the request has already emitted the close
event, the abort operation will have no effect. Otherwise an ongoing event will emit abort
and close
events. Additionally, if there is an ongoing response object,it will emit the aborted
event.
request.followRedirect()
Continues any pending redirection. Can only be called during a 'redirect'
event.
request.getUploadProgress()
Returns Object
:
active
Boolean - Whether the request is currently active. If this is false no other properties will be setstarted
Boolean - Whether the upload has started. If this is false both current
and total
will be set to 0.current
Integer - The number of bytes that have been uploaded so fartotal
Integer - The number of bytes that will be uploaded this requestYou can use this method in conjunction with POST
requests to get the progress of a file upload or other data transfer.
Perform copy and paste operations on the system clipboard.
On Linux, there is also a selection
clipboard. To manipulate it you need to pass selection
to each method:
const { clipboard } = require('electron') clipboard.writeText('Example String', 'selection') console.log(clipboard.readText('selection'))
The clipboard
module has the following methods:
Note: Experimental APIs are marked as such and could be removed in future.
clipboard.readText([type])
type
String (optional) - Can be selection
or clipboard
; default is 'clipboard'. selection
is only available on Linux.Returns String
- The content in the clipboard as plain text.
const { clipboard } = require('electron') clipboard.writeText('hello i am a bit of text!') const text = clipboard.readText() console.log(text) // hello i am a bit of text!'
clipboard.writeText(text[, type])
text
Stringtype
String (optional) - Can be selection
or clipboard
; default is 'clipboard'. selection
is only available on Linux.Writes the text
into the clipboard as plain text.
const { clipboard } = require('electron') const text = 'hello i am a bit of text!' clipboard.writeText(text)
clipboard.readHTML([type])
type
String (optional) - Can be selection
or clipboard
; default is 'clipboard'. selection
is only available on Linux.Returns String
- The content in the clipboard as markup.
const { clipboard } = require('electron') clipboard.writeHTML('<b>Hi</b>') const html = clipboard.readHTML() console.log(html) // <meta charset='utf-8'><b>Hi</b>
clipboard.writeHTML(markup[, type])
markup
Stringtype
String (optional) - Can be selection
or clipboard
; default is 'clipboard'. selection
is only available on Linux.Writes markup
to the clipboard.
const { clipboard } = require('electron') clipboard.writeHTML('<b>Hi</b')
clipboard.readImage([type])
type
String (optional) - Can be selection
or clipboard
; default is 'clipboard'. selection
is only available on Linux.Returns NativeImage
- The image content in the clipboard.
clipboard.writeImage(image[, type])
image
NativeImage
type
String (optional) - Can be selection
or clipboard
; default is 'clipboard'. selection
is only available on Linux.Writes image
to the clipboard.
clipboard.readRTF([type])
type
String (optional) - Can be selection
or clipboard
; default is 'clipboard'. selection
is only available on Linux.Returns String
- The content in the clipboard as RTF.
const { clipboard } = require('electron') clipboard.writeRTF('{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard\nThis is some {\\b bold} text.\\par\n}') const rtf = clipboard.readRTF() console.log(rtf) // {\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard\nThis is some {\\b bold} text.\\par\n}
clipboard.writeRTF(text[, type])
text
Stringtype
String (optional) - Can be selection
or clipboard
; default is 'clipboard'. selection
is only available on Linux.Writes the text
into the clipboard in RTF.
const { clipboard } = require('electron') const rtf = '{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard\nThis is some {\\b bold} text.\\par\n}' clipboard.writeRTF(rtf)
clipboard.readBookmark()
macOS Windows
Returns Object
:
title
Stringurl
StringReturns an Object containing title
and url
keys representing the bookmark in the clipboard. The title
and url
values will be empty strings when the bookmark is unavailable.
clipboard.writeBookmark(title, url[, type])
macOS Windows
title
Stringurl
Stringtype
String (optional) - Can be selection
or clipboard
; default is 'clipboard'. selection
is only available on Linux.Writes the title
and url
into the clipboard as a bookmark.
Note: Most apps on Windows don't support pasting bookmarks into them so you can use clipboard.write
to write both a bookmark and fallback text to the clipboard.
const { clipboard } = require('electron') clipboard.writeBookmark({ text: 'https://electronjs.org', bookmark: 'Electron Homepage' })
clipboard.readFindText()
macOS
Returns String
- The text on the find pasteboard, which is the pasteboard that holds information about the current state of the active application’s find panel.
This method uses synchronous IPC when called from the renderer process. The cached value is reread from the find pasteboard whenever the application is activated.
clipboard.writeFindText(text)
macOS
text
StringWrites the text
into the find pasteboard (the pasteboard that holds information about the current state of the active application’s find panel) as plain text. This method uses synchronous IPC when called from the renderer process.
clipboard.clear([type])
type
String (optional) - Can be selection
or clipboard
; default is 'clipboard'. selection
is only available on Linux.Clears the clipboard content.
clipboard.availableFormats([type])
type
String (optional) - Can be selection
or clipboard
; default is 'clipboard'. selection
is only available on Linux.Returns String[]
- An array of supported formats for the clipboard type
.
const { clipboard } = require('electron') const formats = clipboard.availableFormats() console.log(formats) // [ 'text/plain', 'text/html' ]
clipboard.has(format[, type])
Experimental
format
Stringtype
String (optional) - Can be selection
or clipboard
; default is 'clipboard'. selection
is only available on Linux.Returns Boolean
- Whether the clipboard supports the specified format
.
const { clipboard } = require('electron') const hasFormat = clipboard.has('<p>selection</p>') console.log(hasFormat) // 'true' or 'false
clipboard.read(format)
Experimental
format
StringReturns String
- Reads format
type from the clipboard.
clipboard.readBuffer(format)
Experimental
format
StringReturns Buffer
- Reads format
type from the clipboard.
const { clipboard } = require('electron') const buffer = Buffer.from('this is binary', 'utf8') clipboard.writeBuffer('public.utf8-plain-text', buffer) const ret = clipboard.readBuffer('public.utf8-plain-text') console.log(buffer.equals(out)) // true
clipboard.writeBuffer(format, buffer[, type])
Experimental
format
Stringbuffer
Buffertype
String (optional) - Can be selection
or clipboard
; default is 'clipboard'. selection
is only available on Linux.Writes the buffer
into the clipboard as format
.
const { clipboard } = require('electron') const buffer = Buffer.from('writeBuffer', 'utf8') clipboard.writeBuffer('public.utf8-plain-text', buffer)
clipboard.write(data[, type])
data
Objecttext
String (optional)html
String (optional)image
NativeImage (optional)rtf
String (optional)bookmark
String (optional) - The title of the URL at text
.type
String (optional) - Can be selection
or clipboard
; default is 'clipboard'. selection
is only available on Linux.Writes data
to the clipboard.
const { clipboard } = require('electron') clipboard.write({ text: 'test', html: '<b>Hi</b>', rtf: '{\\rtf1\\utf8 text}', bookmark: 'a title' }) console.log(clipboard.readText()) // 'test' console.log(clipboard.readHTML()) // <meta charset='utf-8'><b>Hi</b> console.log(clipboard.readRTF()) // '{\\rtf1\\utf8 text}' console.log(clipboard.readBookmark()) // { title: 'a title', url: 'test' }
Code signing is a security technology that you use to certify that an app was created by you.
On macOS the system can detect any change to the app, whether the change is introduced accidentally or by malicious code.
On Windows, the system assigns a trust level to your code signing certificate which if you don't have, or if your trust level is low, will cause security dialogs to appear when users start using your application. Trust level builds over time so it's better to start code signing as early as possible.
While it is possible to distribute unsigned apps, it is not recommended. Both Windows and macOS will, by default, prevent either the download or the execution of unsigned applications. Starting with macOS Catalina (version 10.15), users have to go through multiple manual steps to open unsigned applications.
As you can see, users get two options: Move the app straight to the trash or cancel running it. You don't want your users to see that dialog.
If you are building an Electron app that you intend to package and distribute, it should be code-signed.
Properly preparing macOS applications for release requires two steps: First, the app needs to be code-signed. Then, the app needs to be uploaded to Apple for a process called "notarization", where automated systems will further verify that your app isn't doing anything to endanger its users.
To start the process, ensure that you fulfill the requirements for signing and notarizing your app:
Electron's ecosystem favors configuration and freedom, so there are multiple ways to get your application signed and notarized.
electron-forge
If you're using Electron's favorite build tool, getting your application signed and notarized requires a few additions to your configuration. Forge is a collection of the official Electron tools, using electron-packager
, electron-osx-sign
, and electron-notarize
under the hood.
Let's take a look at an example configuration with all required fields. Not all of them are required: the tools will be clever enough to automatically find a suitable identity
, for instance, but we recommend that you are explicit.
{ "name": "my-app", "version": "0.0.1", "config": { "forge": { "packagerConfig": { "osxSign": { "identity": "Developer ID Application: Felix Rieseberg (LT94ZKYDCJ)", "hardened-runtime": true, "entitlements": "entitlements.plist", "entitlements-inherit": "entitlements.plist", "signature-flags": "library" }, "osxNotarize": { "appleId": "[email protected]", "appleIdPassword": "my-apple-id-password", } } } } }
The plist
file referenced here needs the following macOS-specific entitlements to assure the Apple security mechanisms that your app is doing these things without meaning any harm:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.security.cs.allow-jit</key> <true/> <key>com.apple.security.cs.allow-unsigned-executable-memory</key> <true/> <key>com.apple.security.cs.debugger</key> <true/> </dict> </plist>
To see all of this in action, check out Electron Fiddle's source code, especially its electron-forge
configuration file.
If you plan to access the microphone or camera within your app using Electron's APIs, you'll also need to add the following entitlements:
<key>com.apple.security.device.audio-input</key> <true/> <key>com.apple.security.device.camera</key> <true/>
If these are not present in your app's entitlements when you invoke, for example:
const { systemPreferences } = require('electron') const microphone = systemPreferences.askForMediaAccess('microphone')
Your app may crash. See the Resource Access section in Hardened Runtime for more information and entitlements you may need.
electron-builder
Electron Builder comes with a custom solution for signing your application. You can find its documentation here.
electron-packager
If you're not using an integrated build pipeline like Forge or Builder, you are likely using electron-packager
, which includes electron-osx-sign
and electron-notarize
.
If you're using Packager's API, you can pass in configuration that both signs and notarizes your application.
const packager = require('electron-packager') packager({ dir: '/path/to/my/app', osxSign: { identity: 'Developer ID Application: Felix Rieseberg (LT94ZKYDCJ)', 'hardened-runtime': true, entitlements: 'entitlements.plist', 'entitlements-inherit': 'entitlements.plist', 'signature-flags': 'library' }, osxNotarize: { appleId: 'felix@felix.fun', appleIdPassword: 'my-apple-id-password' } })
The plist
file referenced here needs the following macOS-specific entitlements to assure the Apple security mechanisms that your app is doing these things without meaning any harm:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.security.cs.allow-jit</key> <true/> <key>com.apple.security.cs.allow-unsigned-executable-memory</key> <true/> <key>com.apple.security.cs.debugger</key> <true/> </dict> </plist>
See the Mac App Store Guide.
Before signing Windows builds, you must do the following:
You can get a code signing certificate from a lot of resellers. Prices vary, so it may be worth your time to shop around. Popular resellers include:
There are a number of tools for signing your packaged app:
electron-winstaller
will generate an installer for windows and sign it for youelectron-forge
can sign installers it generates through the Squirrel.Windows or MSI targets.electron-builder
can sign some of its windows targetsSee the Windows Store Guide.
These are the style guidelines for coding in Electron.
You can run npm run lint
to show any style issues detected by cpplint
and eslint
.
path
)ipc
, app
)@
)path.join()
to concatenate filenames.os.tmpdir()
rather than /tmp
when you need to reference the temporary directory.return
when returning explicitly at the end of a function.return null
, return undefined
, null
or undefined
For C++ and Python, we follow Chromium's Coding Style. You can use clang-format to format the C++ code automatically. There is also a script script/cpplint.py
to check whether all files conform.
The Python version we are using now is Python 2.7.
The C++ code uses a lot of Chromium's abstractions and types, so it's recommended to get acquainted with them. A good place to start is Chromium's Important Abstractions and Data Structures document. The document mentions some special types, scoped types (that automatically release their memory when going out of scope), logging mechanisms etc.
You can run npm run lint-docs
to ensure that your documentation changes are formatted correctly.
-
instead of _
, e.g. file-name.js
rather than file_name.js
, because in github/atom module names are usually in the module-name
form. This rule only applies to .js
files.const
for requires and other constants. If the value is a primitive, use uppercase naming (eg const NUMBER_OF_RETRIES = 5
).let
for defining variablesfunction () { }
+
Electron APIs uses the same capitalization scheme as Node.js:
BrowserWindow
, use PascalCase
.globalShortcut
, use camelCase
.win.webContents
, use mixedCase
.<webview> Tag
or Process Object
.When creating a new API, it is preferred to use getters and setters instead of jQuery's one-function style. For example, .getText()
and .setText(text)
are preferred to .text([text])
. There is a discussion on this.
Manipulate the command line arguments for your app that Chromium reads
Process: Main
The following example shows how to check if the --disable-gpu
flag is set.
const { app } = require('electron') app.commandLine.hasSwitch('disable-gpu')
For more information on what kinds of flags and switches you can use, check out the Command Line Switches document.
commandLine.appendSwitch(switch[, value])
switch
String - A command-line switch, without the leading --
value
String (optional) - A value for the given switchAppend a switch (with optional value
) to Chromium's command line.
Note: This will not affect process.argv
. The intended usage of this function is to control Chromium's behavior.
commandLine.appendArgument(value)
value
String - The argument to append to the command lineAppend an argument to Chromium's command line. The argument will be quoted correctly. Switches will precede arguments regardless of appending order.
If you're appending an argument like --switch=value
, consider using appendSwitch('switch', 'value')
instead.
Note: This will not affect process.argv
. The intended usage of this function is to control Chromium's behavior.
commandLine.hasSwitch(switch)
switch
String - A command-line switchReturns Boolean
- Whether the command-line switch is present.
commandLine.getSwitchValue(switch)
switch
String - A command-line switchReturns String
- The command-line switch value.
Note: When the switch is not present or has no value, it returns empty string.
Command line switches supported by Electron.
You can use app.commandLine.appendSwitch to append them in your app's main script before the ready event of the app module is emitted:
const { app } = require('electron') app.commandLine.appendSwitch('remote-debugging-port', '8315') app.commandLine.appendSwitch('host-rules', 'MAP * 127.0.0.1') app.whenReady().then(() => { // Your code here })
url
A comma-separated list of servers for which integrated authentication is enabled.
For example:
--auth-server-whitelist='*example.com, *foobar.com, *baz'
then any url
ending with example.com
, foobar.com
, baz
will be considered for integrated authentication. Without *
prefix the URL has to match exactly.
url
A comma-separated list of servers for which delegation of user credentials is required. Without *
prefix the URL has to match exactly.
Disables NTLM v2 for posix platforms, no effect elsewhere.
Disables the disk cache for HTTP requests.
Disable HTTP/2 and SPDY/3.1 protocols.
Prevents Chromium from lowering the priority of invisible pages' renderer processes.
This flag is global to all renderer processes, if you only want to disable throttling in one window, you can take the hack of playing silent audio.
size
Forces the maximum disk space to be used by the disk cache, in bytes.
Enables caller stack logging for the following APIs (filtering events):
desktopCapturer.getSources()
/ desktop-capturer-get-sources
remote.require()
/ remote-require
remote.getGlobal()
/ remote-get-builtin
remote.getBuiltin()
/ remote-get-global
remote.getCurrentWindow()
/ remote-get-current-window
remote.getCurrentWebContents()
/ remote-get-current-web-contents
Prints Chromium's logging into console.
This switch can not be used in app.commandLine.appendSwitch
since it is parsed earlier than user's app is loaded, but you can set the ELECTRON_ENABLE_LOGGING
environment variable to achieve the same effect.
rules
A comma-separated list of rules
that control how hostnames are mapped.
For example:
MAP * 127.0.0.1
Forces all hostnames to be mapped to 127.0.0.1MAP *.google.com proxy
Forces all google.com subdomains to be resolved to "proxy".MAP test.com [::1]:77
Forces "test.com" to resolve to IPv6 loopback. Will also force the port of the resulting socket address to be 77.MAP * baz, EXCLUDE www.google.com
Remaps everything to "baz", except for "www.google.com".These mappings apply to the endpoint host in a net request (the TCP connect and host resolver in a direct connection, and the CONNECT
in an HTTP proxy connection, and the endpoint host in a SOCKS
proxy connection).
rules
Like --host-rules
but these rules
only apply to the host resolver.
Ignores certificate related errors.
domains
Ignore the connections limit for domains
list separated by ,
.
flags
Specifies the flags passed to the Node.js engine. It has to be passed when starting Electron if you want to enable the flags
in the main process.
$ electron --js-flags="--harmony_proxies --harmony_collections" your-app
See the Node.js documentation or run node --help
in your terminal for a list of available flags. Additionally, run node --v8-options
to see a list of flags that specifically refer to Node.js's V8 JavaScript engine.
Set a custom locale.
path
Enables net log events to be saved and writes them to path
.
Don't use a proxy server and always make direct connections. Overrides any other proxy server flags that are passed.
Disables Chromium sandbox, which is now enabled by default. Should only be used for testing.
hosts
Instructs Electron to bypass the proxy server for the given semi-colon-separated list of hosts. This flag has an effect only if used in tandem with --proxy-server
.
For example:
const { app } = require('electron') app.commandLine.appendSwitch('proxy-bypass-list', '<local>;*.google.com;*foo.com;1.2.3.4:5678')
Will use the proxy server for all hosts except for local addresses (localhost
, 127.0.0.1
etc.), google.com
subdomains, hosts that contain the suffix foo.com
and anything at 1.2.3.4:5678
.
url
Uses the PAC script at the specified url
.
address:port
Use a specified proxy server, which overrides the system setting. This switch only affects requests with HTTP protocol, including HTTPS and WebSocket requests. It is also noteworthy that not all proxy servers support HTTPS and WebSocket requests. The proxy URL does not support username and password authentication per Chromium issue.
port
Enables remote debugging over HTTP on the specified port
.
path
Sets the path
of the pepper flash plugin.
version
Sets the version
of the pepper flash plugin.
log_level
Gives the default maximal active V-logging level; 0 is the default. Normally positive values are used for V-logging levels.
This switch only works when --enable-logging
is also passed.
pattern
Gives the per-module maximal V-logging levels to override the value given by --v
. E.g. my_module=2,foo*=3
would change the logging level for all code in source files my_module.*
and foo*.*
.
Any pattern containing a forward or backward slash will be tested against the whole pathname and not only the module. E.g. */foo/bar/*=2
would change the logging level for all code in the source files under a foo/bar
directory.
This switch only works when --enable-logging
is also passed.
Force using discrete GPU when there are multiple GPUs available.
Force using integrated GPU when there are multiple GPUs available.
Electron supports some of the CLI flags supported by Node.js.
Note: Passing unsupported command line switches to Electron when it is not running in ELECTRON_RUN_AS_NODE
will have no effect.
Activate inspector on host:port and break at start of user script. Default host:port is 127.0.0.1:9229.
Aliased to --debug-brk=[host:]port
.
Set the host:port
to be used when the inspector is activated. Useful when activating the inspector by sending the SIGUSR1 signal. Default host is 127.0.0.1
.
Aliased to --debug-port=[host:]port
.
Activate inspector on host:port
. Default is 127.0.0.1:9229
.
V8 inspector integration allows tools such as Chrome DevTools and IDEs to debug and profile Electron instances. The tools attach to Electron instances via a TCP port and communicate using the Chrome DevTools Protocol.
See the Debugging the Main Process guide for more details.
Aliased to --debug[=[host:]port
.
Specify ways of the inspector web socket url exposure.
By default inspector websocket url is available in stderr and under /json/list endpoint on http://host:port/json/list.
Collect tracing data from Chromium to find performance bottlenecks and slow operations.
Process: Main
This module does not include a web interface. To view recorded traces, use trace viewer, available at chrome://tracing
in Chrome.
Note: You should not use this module until the ready
event of the app module is emitted.
const { app, contentTracing } = require('electron') app.whenReady().then(() => { (async () => { await contentTracing.startRecording({ include_categories: ['*'] }) console.log('Tracing started') await new Promise(resolve => setTimeout(resolve, 5000)) const path = await contentTracing.stopRecording() console.log('Tracing data recorded to ' + path) })() })
The contentTracing
module has the following methods:
contentTracing.getCategories()
Returns Promise<String[]>
- resolves with an array of category groups once all child processes have acknowledged the getCategories
request
Get a set of category groups. The category groups can change as new code paths are reached. See also the list of built-in tracing categories.
NOTE: Electron adds a non-default tracing category called
"electron"
. This category can be used to capture Electron-specific tracing events.
contentTracing.startRecording(options)
options
(TraceConfig | TraceCategoriesAndOptions)Returns Promise<void>
- resolved once all child processes have acknowledged the startRecording
request.
Start recording on all processes.
Recording begins immediately locally and asynchronously on child processes as soon as they receive the EnableRecording request.
If a recording is already running, the promise will be immediately resolved, as only one trace operation can be in progress at a time.
contentTracing.stopRecording([resultFilePath])
resultFilePath
String (optional)Returns Promise<String>
- resolves with a path to a file that contains the traced data once all child processes have acknowledged the stopRecording
request
Stop recording on all processes.
Child processes typically cache trace data and only rarely flush and send trace data back to the main process. This helps to minimize the runtime overhead of tracing since sending trace data over IPC can be an expensive operation. So, to end tracing, Chromium asynchronously asks all child processes to flush any pending trace data.
Trace data will be written into resultFilePath
. If resultFilePath
is empty or not provided, trace data will be written to a temporary file, and the path will be returned in the promise.
contentTracing.getTraceBufferUsage()
Returns Promise<Object>
- Resolves with an object containing the value
and percentage
of trace buffer maximum usage
value
Numberpercentage
NumberGet the maximum usage across processes of trace buffer as a percentage of the full state.
Create a safe, bi-directional, synchronous bridge across isolated contexts
Process: Renderer
An example of exposing an API to a renderer from an isolated preload script is given below:
// Preload (Isolated World) const { contextBridge, ipcRenderer } = require('electron') contextBridge.exposeInMainWorld( 'electron', { doThing: () => ipcRenderer.send('do-a-thing') } )
// Renderer (Main World) window.electron.doThing()
The "Main World" is the JavaScript context that your main renderer code runs in. By default, the page you load in your renderer executes code in this world.
When contextIsolation
is enabled in your webPreferences
, your preload
scripts run in an "Isolated World". You can read more about context isolation and what it affects in the security docs.
The contextBridge
module has the following methods:
contextBridge.exposeInMainWorld(apiKey, api)
Experimental
apiKey
String - The key to inject the API onto window
with. The API will be accessible on window[apiKey]
.api
Record<String, any> - Your API object, more information on what this API can be and how it works is available below.The api
object provided to exposeInMainWorld
must be an object whose keys are strings and values are a Function
, String
, Number
, Array
, Boolean
, or another nested object that meets the same conditions.
Function
values are proxied to the other context and all other values are copied and frozen. Any data / primitives sent in the API object become immutable and updates on either side of the bridge do not result in an update on the other side.
An example of a complex API object is shown below:
const { contextBridge } = require('electron') contextBridge.exposeInMainWorld( 'electron', { doThing: () => ipcRenderer.send('do-a-thing'), myPromises: [Promise.resolve(), Promise.reject(new Error('whoops'))], anAsyncFunction: async () => 123, data: { myFlags: ['a', 'b', 'c'], bootTime: 1234 }, nestedAPI: { evenDeeper: { youCanDoThisAsMuchAsYouWant: { fn: () => ({ returnData: 123 }) } } } } )
Function
values that you bind through the contextBridge
are proxied through Electron to ensure that contexts remain isolated. This results in some key limitations that we've outlined below.
Because parameters, errors and return values are copied when they are sent over the bridge, there are only certain types that can be used. At a high level, if the type you want to use can be serialized and deserialized into the same object it will work. A table of type support has been included below for completeness:
Type | Complexity | Parameter Support | Return Value Support | Limitations |
---|---|---|---|---|
String |
Simple | ✅ | ✅ | N/A |
Number |
Simple | ✅ | ✅ | N/A |
Boolean |
Simple | ✅ | ✅ | N/A |
Object |
Complex | ✅ | ✅ | Keys must be supported using only "Simple" types in this table. Values must be supported in this table. Prototype modifications are dropped. Sending custom classes will copy values but not the prototype. |
Array |
Complex | ✅ | ✅ | Same limitations as the Object type |
Error |
Complex | ✅ | ✅ | Errors that are thrown are also copied, this can result in the message and stack trace of the error changing slightly due to being thrown in a different context |
Promise |
Complex | ✅ | ✅ | Promises are only proxied if they are the return value or exact parameter. Promises nested in arrays or objects will be dropped. |
Function |
Complex | ✅ | ✅ | Prototype modifications are dropped. Sending classes or constructors will not work. |
Cloneable Types | Simple | ✅ | ✅ | See the linked document on cloneable types |
Symbol |
N/A | ❌ | ❌ | Symbols cannot be copied across contexts so they are dropped |
If the type you care about is not in the above table, it is probably not supported.
Context Isolation is a feature that ensures that both your preload
scripts and Electron's internal logic run in a separate context to the website you load in a webContents
. This is important for security purposes as it helps prevent the website from accessing Electron internals or the powerful APIs your preload script has access to.
This means that the window
object that your preload script has access to is actually a different object than the website would have access to. For example, if you set window.hello = 'wave'
in your preload script and context isolation is enabled window.hello
will be undefined if the website tries to access it.
Every single application should have context isolation enabled and from Electron 12 it will be enabled by default.
From Electron 12, it will be enabled by default. For lower versions it is an option in the webPreferences
option when constructing new BrowserWindow
's.
const mainWindow = new BrowserWindow({ webPreferences: { contextIsolation: true } })
I used to provide APIs from my preload script using
window.X = apiObject
now what?
Exposing APIs from your preload script to the loaded website is a common usecase and there is a dedicated module in Electron to help you do this in a painless way.
Before: With context isolation disabled
window.myAPI = { doAThing: () => {} }
After: With context isolation enabled
const { contextBridge } = require('electron') contextBridge.exposeInMainWorld('myAPI', { doAThing: () => {} })
The contextBridge
module can be used to safely expose APIs from the isolated context your preload script runs in to the context the website is running in. The API will also be accessible from the website on window.myAPI
just like it was before.
You should read the contextBridge
documentation linked above to fully understand its limitations. For instance you can't send custom prototypes or symbols over the bridge.
Just enabling contextIsolation
and using contextBridge
does not automatically mean that everything you do is safe. For instance this code is unsafe.
// ❌ Bad code contextBridge.exposeInMainWorld('myAPI', { send: ipcRenderer.send })
It directly exposes a powerful API without any kind of argument filtering. This would allow any website to send arbitrary IPC messages which you do not want to be possible. The correct way to expose IPC-based APIs would instead be to provide one method per IPC message.
// ✅ Good code contextBridge.exposeInMainWorld('myAPI', { loadPreferences: () => ipcRenderer.invoke('load-prefs') })
name
String - The name of the cookie.value
String - The value of the cookie.domain
String (optional) - The domain of the cookie; this will be normalized with a preceding dot so that it's also valid for subdomains.hostOnly
Boolean (optional) - Whether the cookie is a host-only cookie; this will only be true
if no domain was passed.path
String (optional) - The path of the cookie.secure
Boolean (optional) - Whether the cookie is marked as secure.httpOnly
Boolean (optional) - Whether the cookie is marked as HTTP only.session
Boolean (optional) - Whether the cookie is a session cookie or a persistent cookie with an expiration date.expirationDate
Double (optional) - The expiration date of the cookie as the number of seconds since the UNIX epoch. Not provided for session cookies.sameSite
String - The Same Site policy applied to this cookie. Can be unspecified
, no_restriction
, lax
or strict
.Query and modify a session's cookies.
Process: Main
Instances of the Cookies
class are accessed by using cookies
property of a Session
.
For example:
const { session } = require('electron') // Query all cookies. session.defaultSession.cookies.get({}) .then((cookies) => { console.log(cookies) }).catch((error) => { console.log(error) }) // Query all cookies associated with a specific url. session.defaultSession.cookies.get({ url: 'http://www.github.com' }) .then((cookies) => { console.log(cookies) }).catch((error) => { console.log(error) }) // Set a cookie with the given cookie data; // may overwrite equivalent cookies if they exist. const cookie = { url: 'http://www.github.com', name: 'dummy_name', value: 'dummy' } session.defaultSession.cookies.set(cookie) .then(() => { // success }, (error) => { console.error(error) })
The following events are available on instances of Cookies
:
event
Eventcookie
Cookie - The cookie that was changed.cause
String - The cause of the change with one of the following values:explicit
- The cookie was changed directly by a consumer's action.overwrite
- The cookie was automatically removed due to an insert operation that overwrote it.expired
- The cookie was automatically removed as it expired.evicted
- The cookie was automatically evicted during garbage collection.expired-overwrite
- The cookie was overwritten with an already-expired expiration date.removed
Boolean - true
if the cookie was removed, false
otherwise.Emitted when a cookie is changed because it was added, edited, removed, or expired.
The following methods are available on instances of Cookies
:
cookies.get(filter)
filter
Objecturl
String (optional) - Retrieves cookies which are associated with url
. Empty implies retrieving cookies of all URLs.name
String (optional) - Filters cookies by name.domain
String (optional) - Retrieves cookies whose domains match or are subdomains of domains
.path
String (optional) - Retrieves cookies whose path matches path
.secure
Boolean (optional) - Filters cookies by their Secure property.session
Boolean (optional) - Filters out session or persistent cookies.Returns Promise<Cookie[]>
- A promise which resolves an array of cookie objects.
Sends a request to get all cookies matching filter
, and resolves a promise with the response.
cookies.set(details)
details
Objecturl
String - The URL to associate the cookie with. The promise will be rejected if the URL is invalid.name
String (optional) - The name of the cookie. Empty by default if omitted.value
String (optional) - The value of the cookie. Empty by default if omitted.domain
String (optional) - The domain of the cookie; this will be normalized with a preceding dot so that it's also valid for subdomains. Empty by default if omitted.path
String (optional) - The path of the cookie. Empty by default if omitted.secure
Boolean (optional) - Whether the cookie should be marked as Secure. Defaults to false.httpOnly
Boolean (optional) - Whether the cookie should be marked as HTTP only. Defaults to false.expirationDate
Double (optional) - The expiration date of the cookie as the number of seconds since the UNIX epoch. If omitted then the cookie becomes a session cookie and will not be retained between sessions.sameSite
String (optional) - The Same Site policy to apply to this cookie. Can be unspecified
, no_restriction
, lax
or strict
. Default is no_restriction
.Returns Promise<void>
- A promise which resolves when the cookie has been set
Sets a cookie with details
.
cookies.remove(url, name)
url
String - The URL associated with the cookie.name
String - The name of cookie to remove.Returns Promise<void>
- A promise which resolves when the cookie has been removed
Removes the cookies matching url
and name
cookies.flushStore()
Returns Promise<void>
- A promise which resolves when the cookie store has been flushed
Writes any unwritten cookies data to disk.
percentCPUUsage
Number - Percentage of CPU used since the last call to getCPUUsage. First call returns 0.idleWakeupsPerSecond
Number - The number of average idle CPU wakeups per second since the last call to getCPUUsage. First call returns 0. Will always return 0 on Windows.date
Dateid
StringSubmit crash reports to a remote server.
The following is an example of setting up Electron to automatically submit crash reports to a remote server:
const { crashReporter } = require('electron') crashReporter.start({ submitURL: 'https://your-domain.com/url-to-submit' })
For setting up a server to accept and process crash reports, you can use following projects:
Or use a 3rd party hosted solution:
Crash reports are stored temporarily before being uploaded in a directory underneath the app's user data directory (called 'Crashpad' on Windows and Mac, or 'Crash Reports' on Linux). You can override this directory by calling app.setPath('crashDumps', '/path/to/crashes')
before starting the crash reporter.
On Windows and macOS, Electron uses crashpad to monitor and report crashes. On Linux, Electron uses breakpad. This is an implementation detail driven by Chromium, and it may change in future. In particular, crashpad is newer and will likely eventually replace breakpad on all platforms.
The crashReporter
module has the following methods:
crashReporter.start(options)
options
ObjectsubmitURL
String - URL that crash reports will be sent to as POST.productName
String (optional) - Defaults to app.name
.companyName
String (optional) Deprecated - Deprecated alias for { globalExtra: { _companyName: ... } }
.uploadToServer
Boolean (optional) - Whether crash reports should be sent to the server. If false, crash reports will be collected and stored in the crashes directory, but not uploaded. Default is true
.ignoreSystemCrashHandler
Boolean (optional) - If true, crashes generated in the main process will not be forwarded to the system crash handler. Default is false
.rateLimit
Boolean (optional) macOS Windows - If true, limit the number of crashes uploaded to 1/hour. Default is false
.compress
Boolean (optional) - If true, crash reports will be compressed and uploaded with Content-Encoding: gzip
. Default is false
.extra
Record<String, String> (optional) - Extra string key/value annotations that will be sent along with crash reports that are generated in the main process. Only string values are supported. Crashes generated in child processes will not contain these extra parameters to crash reports generated from child processes, call addExtraParameter
from the child process.globalExtra
Record<String, String> (optional) - Extra string key/value annotations that will be sent along with any crash reports generated in any process. These annotations cannot be changed once the crash reporter has been started. If a key is present in both the global extra parameters and the process-specific extra parameters, then the global one will take precedence. By default, productName
and the app version are included, as well as the Electron version.This method must be called before using any other crashReporter
APIs. Once initialized this way, the crashpad handler collects crashes from all subsequently created processes. The crash reporter cannot be disabled once started.
This method should be called as early as possible in app startup, preferably before app.on('ready')
. If the crash reporter is not initialized at the time a renderer process is created, then that renderer process will not be monitored by the crash reporter.
Note: You can test out the crash reporter by generating a crash using process.crash()
.
Note: If you need to send additional/updated extra
parameters after your first call start
you can call addExtraParameter
.
Note: Parameters passed in extra
, globalExtra
or set with addExtraParameter
have limits on the length of the keys and values. Key names must be at most 39 bytes long, and values must be no longer than 127 bytes. Keys with names longer than the maximum will be silently ignored. Key values longer than the maximum length will be truncated.
Note: Calling this method from the renderer process is deprecated.
crashReporter.getLastCrashReport()
Returns CrashReport
- The date and ID of the last crash report. Only crash reports that have been uploaded will be returned; even if a crash report is present on disk it will not be returned until it is uploaded. In the case that there are no uploaded reports, null
is returned.
Note: Calling this method from the renderer process is deprecated.
crashReporter.getUploadedReports()
Returns CrashReport[]
:
Returns all uploaded crash reports. Each report contains the date and uploaded ID.
Note: Calling this method from the renderer process is deprecated.
crashReporter.getUploadToServer()
Returns Boolean
- Whether reports should be submitted to the server. Set through the start
method or setUploadToServer
.
Note: Calling this method from the renderer process is deprecated.
crashReporter.setUploadToServer(uploadToServer)
uploadToServer
Boolean - Whether reports should be submitted to the server.This would normally be controlled by user preferences. This has no effect if called before start
is called.
Note: Calling this method from the renderer process is deprecated.
crashReporter.getCrashesDirectory()
Deprecated
Returns String
- The directory where crashes are temporarily stored before being uploaded.
Note: This method is deprecated, use app.getPath('crashDumps')
instead.
crashReporter.addExtraParameter(key, value)
key
String - Parameter key, must be no longer than 39 bytes.value
String - Parameter value, must be no longer than 127 bytes.Set an extra parameter to be sent with the crash report. The values specified here will be sent in addition to any values set via the extra
option when start
was called.
Parameters added in this fashion (or via the extra
parameter to crashReporter.start
) are specific to the calling process. Adding extra parameters in the main process will not cause those parameters to be sent along with crashes from renderer or other child processes. Similarly, adding extra parameters in a renderer process will not result in those parameters being sent with crashes that occur in other renderer processes or in the main process.
Note: Parameters have limits on the length of the keys and values. Key names must be no longer than 39 bytes, and values must be no longer than 20320 bytes. Keys with names longer than the maximum will be silently ignored. Key values longer than the maximum length will be truncated.
Note: On linux values that are longer than 127 bytes will be chunked into multiple keys, each 127 bytes in length. E.g. addExtraParameter('foo', 'a'.repeat(130))
will result in two chunked keys foo__1
and foo__2
, the first will contain the first 127 bytes and the second will contain the remaining 3 bytes. On your crash reporting backend you should stitch together keys in this format.
crashReporter.removeExtraParameter(key)
key
String - Parameter key, must be no longer than 39 bytes.Remove an extra parameter from the current set of parameters. Future crashes will not include this parameter.
crashReporter.getParameters()
Returns Record<String, String>
- The current 'extra' parameters of the crash reporter.
The crash reporter will send the following data to the submitURL
as a multipart/form-data
POST
:
ver
String - The version of Electron.platform
String - e.g. 'win32'.process_type
String - e.g. 'renderer'.guid
String - e.g. '5e1286fc-da97-479e-918b-6bfb0c3d1c72'._version
String - The version in package.json
._productName
String - The product name in the crashReporter
options
object.prod
String - Name of the underlying product. In this case Electron._companyName
String - The company name in the crashReporter
options
object.upload_file_minidump
File - The crash report in the format of minidump
.extra
object in the crashReporter
options
object.scheme
String - Custom schemes to be registered with options.privileges
Object (optional)standard
Boolean (optional) - Default false.secure
Boolean (optional) - Default false.bypassCSP
Boolean (optional) - Default false.allowServiceWorkers
Boolean (optional) - Default false.supportFetchAPI
Boolean (optional) - Default false.corsEnabled
Boolean (optional) - Default false.stream
Boolean (optional) - Default false."Native interfaces" include the file picker, window border, dialogs, context menus, and more - anything where the UI comes from your operating system and not from your app. The default behavior is to opt into this automatic theming from the OS.
If your app has its own dark mode, you should toggle it on and off in sync with the system's dark mode setting. You can do this by using the prefer-color-scheme CSS media query.
If you want to manually switch between light/dark modes, you can do this by setting the desired mode in the themeSource property of the nativeTheme
module. This property's value will be propagated to your Renderer process. Any CSS rules related to prefers-color-scheme
will be updated accordingly.
In macOS 10.14 Mojave, Apple introduced a new system-wide dark mode for all macOS computers. If your Electron app has a dark mode, you can make it follow the system-wide dark mode setting using the nativeTheme
api.
In macOS 10.15 Catalina, Apple introduced a new "automatic" dark mode option for all macOS computers. In order for the nativeTheme.shouldUseDarkColors
and Tray
APIs to work correctly in this mode on Catalina, you need to use Electron >=7.0.0
, or set NSRequiresAquaSystemAppearance
to false
in your Info.plist
file for older versions. Both Electron Packager and Electron Forge have a darwinDarkModeSupport
option to automate the Info.plist
changes during app build time.
If you wish to opt-out while using Electron > 8.0.0, you must set the NSRequiresAquaSystemAppearance
key in the Info.plist
file to true
. Please note that Electron 8.0.0 and above will not let you opt-out of this theming, due to the use of the macOS 10.14 SDK.
We'll start with a working application from the Quick Start Guide and add functionality gradually.
First, let's edit our interface so users can toggle between light and dark modes. This basic UI contains buttons to change the nativeTheme.themeSource
setting and a text element indicating which themeSource
value is selected. By default, Electron follows the system's dark mode preference, so we will hardcode the theme source as "System".
Add the following lines to the index.html
file:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Hello World!</title> <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" /> <link rel="stylesheet" type="text/css" href="./styles.css"> </head> <body> <h1>Hello World!</h1> <p>Current theme source: <strong id="theme-source">System</strong></p> <button id="toggle-dark-mode">Toggle Dark Mode</button> <button id="reset-to-system">Reset to System Theme</button> <script src="renderer.js"></script> </body> </body> </html>
Next, add event listeners that listen for click
events on the toggle buttons. Because the nativeTheme
module only exposed in the Main process, you need to set up each listener's callback to use IPC to send messages to and handle responses from the Main process:
dark-mode:toggle
message (event) to tell the Main process to trigger a theme change, and update the "Current Theme Source" label in the UI based on the response from the Main process.dark-mode:system
message (event) to tell the Main process to use the system color scheme, and update the "Current Theme Source" label to System
.To add listeners and handlers, add the following lines to the renderer.js
file:
const { ipcRenderer } = require('electron') document.getElementById('toggle-dark-mode').addEventListener('click', async () => { const isDarkMode = await ipcRenderer.invoke('dark-mode:toggle') document.getElementById('theme-source').innerHTML = isDarkMode ? 'Dark' : 'Light' }) document.getElementById('reset-to-system').addEventListener('click', async () => { await ipcRenderer.invoke('dark-mode:system') document.getElementById('theme-source').innerHTML = 'System' })
If you run your code at this point, you'll see that your buttons don't do anything just yet, and your Main process will output an error like this when you click on your buttons: Error occurred in handler for 'dark-mode:toggle': No handler registered for 'dark-mode:toggle'
This is expected — we haven't actually touched any nativeTheme
code yet.
Now that we're done wiring the IPC from the Renderer's side, the next step is to update the main.js
file to handle events from the Renderer process.
Depending on the received event, we update the nativeTheme.themeSource
property to apply the desired theme on the system's native UI elements (e.g. context menus) and propagate the preferred color scheme to the Renderer process:
dark-mode:toggle
, we check if the dark theme is currently active using the nativeTheme.shouldUseDarkColors
property, and set the themeSource
to the opposite theme.dark-mode:system
, we reset the themeSource
to system
.const { app, BrowserWindow, ipcMain, nativeTheme } = require('electron') function createWindow () { const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true } }) win.loadFile('index.html') ipcMain.handle('dark-mode:toggle', () => { if (nativeTheme.shouldUseDarkColors) { nativeTheme.themeSource = 'light' } else { nativeTheme.themeSource = 'dark' } return nativeTheme.shouldUseDarkColors }) ipcMain.handle('dark-mode:system', () => { nativeTheme.themeSouce = 'system' }) } app.whenReady().then(createWindow) app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit() } }) app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) { createWindow() } })
The final step is to add a bit of styling to enable dark mode for the web parts of the UI by leveraging the prefers-color-scheme
CSS attribute. The value of prefers-color-scheme
will follow your nativeTheme.themeSource
setting.
Create a styles.css
file and add the following lines:
@media (prefers-color-scheme: dark) { body { background: #333; color: white; } } @media (prefers-color-scheme: light) { body { background: #ddd; color: black; } }
After launching the Electron application, you can change modes or reset the theme to system default by clicking corresponding buttons:
If you experience crashes or issues in Electron that you believe are not caused by your JavaScript application, but instead by Electron itself, debugging can be a little bit tricky, especially for developers not used to native/C++ debugging. However, using Visual Studio, Electron's hosted Symbol Server, and the Electron source code, you can enable step-through debugging with breakpoints inside Electron's source code.
See also: There's a wealth of information on debugging Chromium, much of which also applies to Electron, on the Chromium developers site: Debugging Chromium on Windows.
A debug build of Electron: The easiest way is usually building it yourself, using the tools and prerequisites listed in the build instructions for Windows. While you can attach to and debug Electron as you can download it directly, you will find that it is heavily optimized, making debugging substantially more difficult: The debugger will not be able to show you the content of all variables and the execution path can seem strange because of inlining, tail calls, and other compiler optimizations.
Visual Studio with C++ Tools: The free community editions of Visual Studio 2013 and Visual Studio 2015 both work. Once installed, configure Visual Studio to use Electron's Symbol server. It will enable Visual Studio to gain a better understanding of what happens inside Electron, making it easier to present variables in a human-readable format.
ProcMon: The free SysInternals tool allows you to inspect a processes parameters, file handles, and registry operations.
To start a debugging session, open up PowerShell/CMD and execute your debug build of Electron, using the application to open as a parameter.
$ ./out/Testing/electron.exe ~/my-electron-app/
Then, open up Visual Studio. Electron is not built with Visual Studio and hence does not contain a project file - you can however open up the source code files "As File", meaning that Visual Studio will open them up by themselves. You can still set breakpoints - Visual Studio will automatically figure out that the source code matches the code running in the attached process and break accordingly.
Relevant code files can be found in ./shell/
.
You can attach the Visual Studio debugger to a running process on a local or remote computer. After the process is running, click Debug / Attach to Process (or press CTRL+ALT+P
) to open the "Attach to Process" dialog box. You can use this capability to debug apps that are running on a local or remote computer, debug multiple processes simultaneously.
If Electron is running under a different user account, select the Show processes from all users
check box. Notice that depending on how many BrowserWindows your app opened, you will see multiple processes. A typical one-window app will result in Visual Studio presenting you with two Electron.exe
entries - one for the main process and one for the renderer process. Since the list only gives you names, there's currently no reliable way of figuring out which is which.
Code executed within the main process (that is, code found in or eventually run by your main JavaScript file) will run inside the main process, while other code will execute inside its respective renderer process.
You can be attached to multiple programs when you are debugging, but only one program is active in the debugger at any time. You can set the active program in the Debug Location
toolbar or the Processes window
.
While Visual Studio is fantastic for inspecting specific code paths, ProcMon's strength is really in observing everything your application is doing with the operating system - it captures File, Registry, Network, Process, and Profiling details of processes. It attempts to log all events occurring and can be quite overwhelming, but if you seek to understand what and how your application is doing to the operating system, it can be a valuable resource.
For an introduction to ProcMon's basic and advanced debugging features, go check out this video tutorial provided by Microsoft.
An alternate transport for Chrome's remote debugging protocol.
Process: Main
Chrome Developer Tools has a special binding available at JavaScript runtime that allows interacting with pages and instrumenting them.
const { BrowserWindow } = require('electron') const win = new BrowserWindow() try { win.webContents.debugger.attach('1.1') } catch (err) { console.log('Debugger attach failed : ', err) } win.webContents.debugger.on('detach', (event, reason) => { console.log('Debugger detached due to : ', reason) }) win.webContents.debugger.on('message', (event, method, params) => { if (method === 'Network.requestWillBeSent') { if (params.request.url === 'https://www.github.com') { win.webContents.debugger.detach() } } }) win.webContents.debugger.sendCommand('Network.enable')
Returns:
event
Eventreason
String - Reason for detaching debugger.Emitted when the debugging session is terminated. This happens either when webContents
is closed or devtools is invoked for the attached webContents
.
Returns:
event
Eventmethod
String - Method name.params
any - Event parameters defined by the 'parameters' attribute in the remote debugging protocol.sessionId
String - Unique identifier of attached debugging session, will match the value sent from debugger.sendCommand
.Emitted whenever the debugging target issues an instrumentation event.
debugger.attach([protocolVersion])
protocolVersion
String (optional) - Requested debugging protocol version.Attaches the debugger to the webContents
.
debugger.isAttached()
Returns Boolean
- Whether a debugger is attached to the webContents
.
debugger.detach()
Detaches the debugger from the webContents
.
debugger.sendCommand(method[, commandParams, sessionId])
method
String - Method name, should be one of the methods defined by the remote debugging protocol.commandParams
any (optional) - JSON object with request parameters.sessionId
String (optional) - send command to the target with associated debugging session id. The initial value can be obtained by sending Target.attachToTarget message.Returns Promise<any>
- A promise that resolves with the response defined by the 'returns' attribute of the command description in the remote debugging protocol or is rejected indicating the failure of the command.
Send given command to the debugging target.
If you experience crashes or issues in Electron that you believe are not caused by your JavaScript application, but instead by Electron itself, debugging can be a little bit tricky, especially for developers not used to native/C++ debugging. However, using lldb, and the Electron source code, you can enable step-through debugging with breakpoints inside Electron's source code. You can also use XCode for debugging if you prefer a graphical interface.
A debug build of Electron: The easiest way is usually building it yourself, using the tools and prerequisites listed in the build instructions for macOS. While you can attach to and debug Electron as you can download it directly, you will find that it is heavily optimized, making debugging substantially more difficult: The debugger will not be able to show you the content of all variables and the execution path can seem strange because of inlining, tail calls, and other compiler optimizations.
Xcode: In addition to Xcode, also install the Xcode command line tools. They include LLDB, the default debugger in Xcode on macOS. It supports debugging C, Objective-C and C++ on the desktop and iOS devices and simulator.
.lldbinit: Create or edit ~/.lldbinit
to allow Chromium code to be properly source-mapped.
command script import ~/electron/src/tools/lldb/lldbinit.py
To start a debugging session, open up Terminal and start lldb
, passing a non-release build of Electron as a parameter.
$ lldb ./out/Testing/Electron.app (lldb) target create "./out/Testing/Electron.app" Current executable set to './out/Testing/Electron.app' (x86_64).
LLDB is a powerful tool and supports multiple strategies for code inspection. For this basic introduction, let's assume that you're calling a command from JavaScript that isn't behaving correctly - so you'd like to break on that command's C++ counterpart inside the Electron source.
Relevant code files can be found in ./shell/
.
Let's assume that you want to debug app.setName()
, which is defined in browser.cc
as Browser::SetName()
. Set the breakpoint using the breakpoint
command, specifying file and line to break on:
(lldb) breakpoint set --file browser.cc --line 117 Breakpoint 1: where = Electron Framework`atom::Browser::SetName(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) + 20 at browser.cc:118, address = 0x000000000015fdb4
Then, start Electron:
(lldb) run
The app will immediately be paused, since Electron sets the app's name on launch:
(lldb) run Process 25244 launched: '/Users/fr/Code/electron/out/Testing/Electron.app/Contents/MacOS/Electron' (x86_64) Process 25244 stopped * thread #1: tid = 0x839a4c, 0x0000000100162db4 Electron Framework`atom::Browser::SetName(this=0x0000000108b14f20, name="Electron") + 20 at browser.cc:118, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 frame #0: 0x0000000100162db4 Electron Framework`atom::Browser::SetName(this=0x0000000108b14f20, name="Electron") + 20 at browser.cc:118 115 } 116 117 void Browser::SetName(const std::string& name) { -> 118 name_override_ = name; 119 } 120 121 int Browser::GetBadgeCount() { (lldb)
To show the arguments and local variables for the current frame, run frame variable
(or fr v
), which will show you that the app is currently setting the name to "Electron".
(lldb) frame variable (atom::Browser *) this = 0x0000000108b14f20 (const string &) name = "Electron": { [...] }
To do a source level single step in the currently selected thread, execute step
(or s
). This would take you into name_override_.empty()
. To proceed and do a step over, run next
(or n
).
(lldb) step Process 25244 stopped * thread #1: tid = 0x839a4c, 0x0000000100162dcc Electron Framework`atom::Browser::SetName(this=0x0000000108b14f20, name="Electron") + 44 at browser.cc:119, queue = 'com.apple.main-thread', stop reason = step in frame #0: 0x0000000100162dcc Electron Framework`atom::Browser::SetName(this=0x0000000108b14f20, name="Electron") + 44 at browser.cc:119 116 117 void Browser::SetName(const std::string& name) { 118 name_override_ = name; -> 119 } 120 121 int Browser::GetBadgeCount() { 122 return badge_count_;
NOTE: If you don't see source code when you think you should, you may not have added the ~/.lldbinit
file above.
To finish debugging at this point, run process continue
. You can also continue until a certain line is hit in this thread (thread until 100
). This command will run the thread in the current frame till it reaches line 100 in this frame or stops if it leaves the current frame.
Now, if you open up Electron's developer tools and call setName
, you will once again hit the breakpoint.
LLDB is a powerful tool with a great documentation. To learn more about it, consider Apple's debugging documentation, for instance the LLDB Command Structure Reference or the introduction to Using LLDB as a Standalone Debugger.
You can also check out LLDB's fantastic manual and tutorial, which will explain more complex debugging scenarios.
Run gn gen
with the --ide=xcode argument.
$ gn gen out/Testing --ide=xcode
This will generate the electron.ninja.xcworkspace. You will have to open this workspace to set breakpoints and inspect.
See gn help gen
for more information on generating IDE projects with GN.
Launch Electron app after build. You can now open the xcode workspace created above and attach to the Electron process through the Debug > Attach To Process > Electron debug menu. [Note: If you want to debug the renderer process, you need to attach to the Electron Helper as well.]
You can now set breakpoints in any of the indexed files. However, you will not be able to set breakpoints directly in the Chromium source. To set break points in the Chromium source, you can choose Debug > Breakpoints > Create Symbolic Breakpoint and set any function name as the symbol. This will set the breakpoint for all functions with that name, from all the classes if there are more than one. You can also do this step of setting break points prior to attaching the debugger, however, actual breakpoints for symbolic breakpoint functions may not show up until the debugger is attached to the app.
The DevTools in an Electron browser window can only debug JavaScript that's executed in that window (i.e. the web pages). To debug JavaScript that's executed in the main process you will need to use an external debugger and launch Electron with the --inspect
or --inspect-brk
switch.
Use one of the following command line switches to enable debugging of the main process:
--inspect=[port]
Electron will listen for V8 inspector protocol messages on the specified port
, an external debugger will need to connect on this port. The default port
is 5858
.
electron --inspect=5858 your/app
--inspect-brk=[port]
Like --inspect
but pauses execution on the first line of JavaScript.
You will need to use a debugger that supports the V8 inspector protocol.
chrome://inspect
and selecting to inspect the launched Electron app present there.This guide goes over how to set up VSCode debugging for both your own Electron project as well as the native Electron codebase.
$ git clone [email protected]:electron/electron-quick-start.git $ code electron-quick-start
.vscode/launch.json
with the following configuration:{ "version": "0.2.0", "configurations": [ { "name": "Debug Main Process", "type": "node", "request": "launch", "cwd": "${workspaceFolder}", "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron", "windows": { "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron.cmd" }, "args" : ["."], "outputCapture": "std" } ] }
Set some breakpoints in main.js
, and start debugging in the Debug View. You should be able to hit the breakpoints.
Here is a pre-configured project that you can download and directly debug in VSCode: https://github.com/octref/vscode-electron-debug/tree/master/electron-quick-start
If you want to build Electron from source and modify the native Electron codebase, this section will help you in testing your modifications.
For those unsure where to acquire this code or how to build it, Electron's Build Tools automates and explains most of this process. If you wish to manually set up the environment, you can instead use these build instructions.
$ git clone [email protected]:electron/electron-quick-start.git $ code electron-quick-start
.vscode/launch.json
with the following configuration:{ "version": "0.2.0", "configurations": [ { "name": "(Windows) Launch", "type": "cppvsdbg", "request": "launch", "program": "${workspaceFolder}\\out\\your-executable-location\\electron.exe", "args": ["your-electron-project-path"], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [ {"name": "ELECTRON_ENABLE_LOGGING", "value": "true"}, {"name": "ELECTRON_ENABLE_STACK_DUMPING", "value": "true"}, {"name": "ELECTRON_RUN_AS_NODE", "value": ""}, ], "externalConsole": false, "sourceFileMap": { "o:\\": "${workspaceFolder}", }, }, ] }
Configuration Notes
cppvsdbg
requires the built-in C/C++ extension be enabled.${workspaceFolder}
is the full path to Chromium's src
directory.your-executable-location
will be one of the following depending on a few items:Testing
: If you are using the default settings of Electron's Build-Tools or the default instructions when building from source.Release
: If you built a Release build rather than a Testing build.your-directory-name
: If you modified this during your build process from the default, this will be whatever you specified.args
array string "your-electron-project-path"
should be the absolute path to either the directory or main.js
file of the Electron project you are using for testing. In this example, it should be your path to electron-quick-start
.Set some breakpoints in the .cc files of your choosing in the native Electron C++ code, and start debugging in the Debug View.
Access information about media sources that can be used to capture audio and video from the desktop using the
navigator.mediaDevices.getUserMedia
API.
The following example shows how to capture video from a desktop window whose title is Electron
:
// In the renderer process. const { desktopCapturer } = require('electron') desktopCapturer.getSources({ types: ['window', 'screen'] }).then(async sources => { for (const source of sources) { if (source.name === 'Electron') { try { const stream = await navigator.mediaDevices.getUserMedia({ audio: false, video: { mandatory: { chromeMediaSource: 'desktop', chromeMediaSourceId: source.id, minWidth: 1280, maxWidth: 1280, minHeight: 720, maxHeight: 720 } } }) handleStream(stream) } catch (e) { handleError(e) } return } } }) function handleStream (stream) { const video = document.querySelector('video') video.srcObject = stream video.onloadedmetadata = (e) => video.play() } function handleError (e) { console.log(e) }
To capture video from a source provided by desktopCapturer
the constraints passed to navigator.mediaDevices.getUserMedia
must include chromeMediaSource: 'desktop'
, and audio: false
.
To capture both audio and video from the entire desktop the constraints passed to navigator.mediaDevices.getUserMedia
must include chromeMediaSource: 'desktop'
, for both audio
and video
, but should not include a chromeMediaSourceId
constraint.
const constraints = { audio: { mandatory: { chromeMediaSource: 'desktop' } }, video: { mandatory: { chromeMediaSource: 'desktop' } } }
The desktopCapturer
module has the following methods:
desktopCapturer.getSources(options)
options
Objecttypes
String[] - An array of Strings that lists the types of desktop sources to be captured, available types are screen
and window
.thumbnailSize
Size (optional) - The size that the media source thumbnail should be scaled to. Default is 150
x 150
. Set width or height to 0 when you do not need the thumbnails. This will save the processing time required for capturing the content of each window and screen.fetchWindowIcons
Boolean (optional) - Set to true to enable fetching window icons. The default value is false. When false the appIcon property of the sources return null. Same if a source has the type screen.Returns Promise<DesktopCapturerSource[]>
- Resolves with an array of DesktopCapturerSource
objects, each DesktopCapturerSource
represents a screen or an individual window that can be captured.
Note Capturing the screen contents requires user consent on macOS 10.15 Catalina or higher, which can detected by systemPreferences.getMediaAccessStatus
.
navigator.mediaDevices.getUserMedia
does not work on macOS for audio capture due to a fundamental limitation whereby apps that want to access the system's audio require a signed kernel extension. Chromium, and by extension Electron, does not provide this.
It is possible to circumvent this limitation by capturing system audio with another macOS app like Soundflower and passing it through a virtual audio input device. This virtual device can then be queried with navigator.mediaDevices.getUserMedia
.
id
String - The identifier of a window or screen that can be used as a chromeMediaSourceId
constraint when calling [navigator.webkitGetUserMedia
]. The format of the identifier will be window:XX
or screen:XX
, where XX
is a random generated number.name
String - A screen source will be named either Entire Screen
or Screen <index>
, while the name of a window source will match the window title.thumbnail
NativeImage - A thumbnail image. Note: There is no guarantee that the size of the thumbnail is the same as the thumbnailSize
specified in the options
passed to desktopCapturer.getSources
. The actual size depends on the scale of the screen or window.display_id
String - A unique identifier that will correspond to the id
of the matching Display returned by the Screen API. On some platforms, this is equivalent to the XX
portion of the id
field above and on others it will differ. It will be an empty string if not available.appIcon
NativeImage - An icon image of the application that owns the window or null if the source has a type screen. The size of the icon is not known in advance and depends on what the application provides.Different operating systems provide different features for integrating desktop applications into their desktop environments. For example, on Windows, applications can put shortcuts in the JumpList of task bar, and on Mac, applications can put a custom menu in the dock menu.
This guide explains how to integrate your application into those desktop environments with Electron APIs.
See the Notifications documentation.
See Recent Documents documentation.
See the Progress Bar documentation.
See the Unity Launcher documentation.
See the Represented File documentation.
See the Native File Drag & Drop documentation.
Electron development is essentially Node.js development. To turn your operating system into an environment capable of building desktop apps with Electron, you will merely need Node.js, npm, a code editor of your choice, and a rudimentary understanding of your operating system's command line client.
Electron supports macOS 10.10 (Yosemite) and up. Apple does not allow running macOS in virtual machines unless the host computer is already an Apple computer, so if you find yourself in need of a Mac, consider using a cloud service that rents access to Macs (like MacInCloud or xcloud).
First, install a recent version of Node.js. We recommend that you install either the latest LTS
or Current
version available. Visit the Node.js download page and select the macOS Installer
. While Homebrew is an offered option, but we recommend against it - many tools will be incompatible with the way Homebrew installs Node.js.
Once downloaded, execute the installer and let the installation wizard guide you through the installation.
Once installed, confirm that everything works as expected. Find the macOS Terminal
application in your /Applications/Utilities
folder (or by searching for the word Terminal
in Spotlight). Open up Terminal
or another command line client of your choice and confirm that both node
and npm
are available:
# This command should print the version of Node.js node -v # This command should print the version of npm npm -v
If both commands printed a version number, you are all set! Before you get started, you might want to install a code editor suited for JavaScript development.
Electron supports Windows 7 and later versions – attempting to develop Electron applications on earlier versions of Windows will not work. Microsoft provides free virtual machine images with Windows 10 for developers.
First, install a recent version of Node.js. We recommend that you install either the latest LTS
or Current
version available. Visit the Node.js download page and select the Windows Installer
. Once downloaded, execute the installer and let the installation wizard guide you through the installation.
On the screen that allows you to configure the installation, make sure to select the Node.js runtime
, npm package manager
, and Add to PATH
options.
Once installed, confirm that everything works as expected. Find the Windows PowerShell by opening the Start Menu and typing PowerShell
. Open up PowerShell
or another command line client of your choice and confirm that both node
and npm
are available:
# This command should print the version of Node.js node -v # This command should print the version of npm npm -v
If both commands printed a version number, you are all set! Before you get started, you might want to install a code editor suited for JavaScript development.
Generally speaking, Electron supports Ubuntu 12.04, Fedora 21, Debian 8 and later.
First, install a recent version of Node.js. Depending on your Linux distribution, the installation steps might differ. Assuming that you normally install software using a package manager like apt
or pacman
, use the official Node.js guidance on installing on Linux.
You're running Linux, so you likely already know how to operate a command line client. Open up your favorite client and confirm that both node
and npm
are available globally:
# This command should print the version of Node.js node -v # This command should print the version of npm npm -v
If both commands printed a version number, you are all set! Before you get started, you might want to install a code editor suited for JavaScript development.
We might suggest two free popular editors built in Electron: GitHub's Atom and Microsoft's Visual Studio Code. Both of them have excellent JavaScript support.
If you are one of the many developers with a strong preference, know that virtually all code editors and IDEs these days support JavaScript.
Electron supports the Chrome DevTools Extension, which can be used to extend the ability of devtools for debugging popular web frameworks.
This document outlines the process for manually loading an extension. You may also try electron-devtools-installer, a third-party tool that downloads extensions directly from the Chrome WebStore.
To load an extension in Electron, you need to download it in Chrome browser, locate its filesystem path, and then load it by calling the BrowserWindow.addDevToolsExtension(extension)
API.
Using the React Developer Tools as example:
Install it in Chrome browser.
Navigate to chrome://extensions
, and find its extension ID, which is a hash string like fmkadmapgofadopljbjfkapdkoienihi
.
Find out filesystem location used by Chrome for storing extensions:
%LOCALAPPDATA%\Google\Chrome\User Data\Default\Extensions
;~/.config/google-chrome/Default/Extensions/
~/.config/google-chrome-beta/Default/Extensions/
~/.config/google-chrome-canary/Default/Extensions/
~/.config/chromium/Default/Extensions/
~/Library/Application Support/Google/Chrome/Default/Extensions
.Pass the location of the extension to BrowserWindow.addDevToolsExtension
API, for the React Developer Tools, it is something like:
const path = require('path') const os = require('os') BrowserWindow.addDevToolsExtension( path.join(os.homedir(), '/Library/Application Support/Google/Chrome/Default/Extensions/fmkadmapgofadopljbjfkapdkoienihi/4.3.0_0') )
Note: The BrowserWindow.addDevToolsExtension
API cannot be called before the ready event of the app module is emitted.
The extension will be remembered so you only need to call this API once per extension. If you try to add an extension that has already been loaded, this method will not return and instead log a warning to the console.
You can pass the name of the extension to the BrowserWindow.removeDevToolsExtension
API to remove it. The name of the extension is returned by BrowserWindow.addDevToolsExtension
and you can get the names of all installed DevTools Extensions using the BrowserWindow.getDevToolsExtensions
API.
Electron only supports a limited set of chrome.*
APIs, so some extensions using unsupported chrome.*
APIs for chrome extension features may not work. Following Devtools Extensions are tested and guaranteed to work in Electron:
First please make sure the extension is still being maintained, some extensions can not even work for recent versions of Chrome browser, and we are not able to do anything for them.
Then file a bug at Electron's issues list, and describe which part of the extension is not working as expected.
Display native system dialogs for opening and saving files, alerting, etc.
Process: Main
An example of showing a dialog to select multiple files:
const { dialog } = require('electron') console.log(dialog.showOpenDialog({ properties: ['openFile', 'multiSelections'] }))
The Dialog is opened from Electron's main thread. If you want to use the dialog object from a renderer process, remember to access it using the remote:
const { dialog } = require('electron').remote console.log(dialog)
The dialog
module has the following methods:
dialog.showOpenDialogSync([browserWindow, ]options)
browserWindow
BrowserWindow (optional)options
Objecttitle
String (optional)defaultPath
String (optional)buttonLabel
String (optional) - Custom label for the confirmation button, when left empty the default label will be used.filters
FileFilter[] (optional)properties
String[] (optional) - Contains which features the dialog should use. The following values are supported:openFile
- Allow files to be selected.openDirectory
- Allow directories to be selected.multiSelections
- Allow multiple paths to be selected.showHiddenFiles
- Show hidden files in dialog.createDirectory
macOS - Allow creating new directories from dialog.promptToCreate
Windows - Prompt for creation if the file path entered in the dialog does not exist. This does not actually create the file at the path but allows non-existent paths to be returned that should be created by the application.noResolveAliases
macOS - Disable the automatic alias (symlink) path resolution. Selected aliases will now return the alias path instead of their target path.treatPackageAsDirectory
macOS - Treat packages, such as .app
folders, as a directory instead of a file.dontAddToRecent
Windows - Do not add the item being opened to the recent documents list.message
String (optional) macOS - Message to display above input boxes.securityScopedBookmarks
Boolean (optional) macOS mas - Create security scoped bookmarks when packaged for the Mac App Store.Returns String[] | undefined
, the file paths chosen by the user; if the dialog is cancelled it returns undefined
.
The browserWindow
argument allows the dialog to attach itself to a parent window, making it modal.
The filters
specifies an array of file types that can be displayed or selected when you want to limit the user to a specific type. For example:
{ filters: [ { name: 'Images', extensions: ['jpg', 'png', 'gif'] }, { name: 'Movies', extensions: ['mkv', 'avi', 'mp4'] }, { name: 'Custom File Type', extensions: ['as'] }, { name: 'All Files', extensions: ['*'] } ] }
The extensions
array should contain extensions without wildcards or dots (e.g. 'png'
is good but '.png'
and '*.png'
are bad). To show all files, use the '*'
wildcard (no other wildcard is supported).
Note: On Windows and Linux an open dialog can not be both a file selector and a directory selector, so if you set properties
to ['openFile', 'openDirectory']
on these platforms, a directory selector will be shown.
dialog.showOpenDialogSync(mainWindow, { properties: ['openFile', 'openDirectory'] })
dialog.showOpenDialog([browserWindow, ]options)
browserWindow
BrowserWindow (optional)options
Objecttitle
String (optional)defaultPath
String (optional)buttonLabel
String (optional) - Custom label for the confirmation button, when left empty the default label will be used.filters
FileFilter[] (optional)properties
String[] (optional) - Contains which features the dialog should use. The following values are supported:openFile
- Allow files to be selected.openDirectory
- Allow directories to be selected.multiSelections
- Allow multiple paths to be selected.showHiddenFiles
- Show hidden files in dialog.createDirectory
macOS - Allow creating new directories from dialog.promptToCreate
Windows - Prompt for creation if the file path entered in the dialog does not exist. This does not actually create the file at the path but allows non-existent paths to be returned that should be created by the application.noResolveAliases
macOS - Disable the automatic alias (symlink) path resolution. Selected aliases will now return the alias path instead of their target path.treatPackageAsDirectory
macOS - Treat packages, such as .app
folders, as a directory instead of a file.dontAddToRecent
Windows - Do not add the item being opened to the recent documents list.message
String (optional) macOS - Message to display above input boxes.securityScopedBookmarks
Boolean (optional) macOS mas - Create security scoped bookmarks when packaged for the Mac App Store.Returns Promise<Object>
- Resolve with an object containing the following:
canceled
Boolean - whether or not the dialog was canceled.filePaths
String[] - An array of file paths chosen by the user. If the dialog is cancelled this will be an empty array.bookmarks
String[] (optional) macOS mas - An array matching the filePaths
array of base64 encoded strings which contains security scoped bookmark data. securityScopedBookmarks
must be enabled for this to be populated. (For return values, see table here.)The browserWindow
argument allows the dialog to attach itself to a parent window, making it modal.
The filters
specifies an array of file types that can be displayed or selected when you want to limit the user to a specific type. For example:
{ filters: [ { name: 'Images', extensions: ['jpg', 'png', 'gif'] }, { name: 'Movies', extensions: ['mkv', 'avi', 'mp4'] }, { name: 'Custom File Type', extensions: ['as'] }, { name: 'All Files', extensions: ['*'] } ] }
The extensions
array should contain extensions without wildcards or dots (e.g. 'png'
is good but '.png'
and '*.png'
are bad). To show all files, use the '*'
wildcard (no other wildcard is supported).
Note: On Windows and Linux an open dialog can not be both a file selector and a directory selector, so if you set properties
to ['openFile', 'openDirectory']
on these platforms, a directory selector will be shown.
dialog.showOpenDialog(mainWindow, { properties: ['openFile', 'openDirectory'] }).then(result => { console.log(result.canceled) console.log(result.filePaths) }).catch(err => { console.log(err) })
dialog.showSaveDialogSync([browserWindow, ]options)
browserWindow
BrowserWindow (optional)options
Objecttitle
String (optional)defaultPath
String (optional) - Absolute directory path, absolute file path, or file name to use by default.buttonLabel
String (optional) - Custom label for the confirmation button, when left empty the default label will be used.filters
FileFilter[] (optional)message
String (optional) macOS - Message to display above text fields.nameFieldLabel
String (optional) macOS - Custom label for the text displayed in front of the filename text field.showsTagField
Boolean (optional) macOS - Show the tags input box, defaults to true
.properties
String[] (optional)showHiddenFiles
- Show hidden files in dialog.createDirectory
macOS - Allow creating new directories from dialog.treatPackageAsDirectory
macOS - Treat packages, such as .app
folders, as a directory instead of a file.showOverwriteConfirmation
Linux - Sets whether the user will be presented a confirmation dialog if the user types a file name that already exists.dontAddToRecent
Windows - Do not add the item being saved to the recent documents list.securityScopedBookmarks
Boolean (optional) macOS mas - Create a security scoped bookmark when packaged for the Mac App Store. If this option is enabled and the file doesn't already exist a blank file will be created at the chosen path.Returns String | undefined
, the path of the file chosen by the user; if the dialog is cancelled it returns undefined
.
The browserWindow
argument allows the dialog to attach itself to a parent window, making it modal.
The filters
specifies an array of file types that can be displayed, see dialog.showOpenDialog
for an example.
dialog.showSaveDialog([browserWindow, ]options)
browserWindow
BrowserWindow (optional)options
Objecttitle
String (optional)defaultPath
String (optional) - Absolute directory path, absolute file path, or file name to use by default.buttonLabel
String (optional) - Custom label for the confirmation button, when left empty the default label will be used.filters
FileFilter[] (optional)message
String (optional) macOS - Message to display above text fields.nameFieldLabel
String (optional) macOS - Custom label for the text displayed in front of the filename text field.showsTagField
Boolean (optional) macOS - Show the tags input box, defaults to true
.properties
String[] (optional)showHiddenFiles
- Show hidden files in dialog.createDirectory
macOS - Allow creating new directories from dialog.treatPackageAsDirectory
macOS - Treat packages, such as .app
folders, as a directory instead of a file.showOverwriteConfirmation
Linux - Sets whether the user will be presented a confirmation dialog if the user types a file name that already exists.dontAddToRecent
Windows - Do not add the item being saved to the recent documents list.securityScopedBookmarks
Boolean (optional) macOS mas - Create a security scoped bookmark when packaged for the Mac App Store. If this option is enabled and the file doesn't already exist a blank file will be created at the chosen path.Returns Promise<Object>
- Resolve with an object containing the following:
canceled
Boolean - whether or not the dialog was canceled.filePath
String (optional) - If the dialog is canceled, this will be undefined
.bookmark
String (optional) macOS mas - Base64 encoded string which contains the security scoped bookmark data for the saved file. securityScopedBookmarks
must be enabled for this to be present. (For return values, see table here.)The browserWindow
argument allows the dialog to attach itself to a parent window, making it modal.
The filters
specifies an array of file types that can be displayed, see dialog.showOpenDialog
for an example.
Note: On macOS, using the asynchronous version is recommended to avoid issues when expanding and collapsing the dialog.
dialog.showMessageBoxSync([browserWindow, ]options)
browserWindow
BrowserWindow (optional)options
Objecttype
String (optional) - Can be "none"
, "info"
, "error"
, "question"
or "warning"
. On Windows, "question"
displays the same icon as "info"
, unless you set an icon using the "icon"
option. On macOS, both "warning"
and "error"
display the same warning icon.buttons
String[] (optional) - Array of texts for buttons. On Windows, an empty array will result in one button labeled "OK".defaultId
Integer (optional) - Index of the button in the buttons array which will be selected by default when the message box opens.title
String (optional) - Title of the message box, some platforms will not show it.message
String - Content of the message box.detail
String (optional) - Extra information of the message.checkboxLabel
String (optional) - If provided, the message box will include a checkbox with the given label.checkboxChecked
Boolean (optional) - Initial checked state of the checkbox. false
by default.icon
(NativeImage | String) (optional)cancelId
Integer (optional) - The index of the button to be used to cancel the dialog, via the Esc
key. By default this is assigned to the first button with "cancel" or "no" as the label. If no such labeled buttons exist and this option is not set, 0
will be used as the return value.noLink
Boolean (optional) - On Windows Electron will try to figure out which one of the buttons
are common buttons (like "Cancel" or "Yes"), and show the others as command links in the dialog. This can make the dialog appear in the style of modern Windows apps. If you don't like this behavior, you can set noLink
to true
.normalizeAccessKeys
Boolean (optional) - Normalize the keyboard access keys across platforms. Default is false
. Enabling this assumes &
is used in the button labels for the placement of the keyboard shortcut access key and labels will be converted so they work correctly on each platform, &
characters are removed on macOS, converted to _
on Linux, and left untouched on Windows. For example, a button label of Vie&w
will be converted to Vie_w
on Linux and View
on macOS and can be selected via Alt-W
on Windows and Linux.Returns Integer
- the index of the clicked button.
Shows a message box, it will block the process until the message box is closed. It returns the index of the clicked button.
The browserWindow
argument allows the dialog to attach itself to a parent window, making it modal. If browserWindow
is not shown dialog will not be attached to it. In such case it will be displayed as an independent window.
dialog.showMessageBox([browserWindow, ]options)
browserWindow
BrowserWindow (optional)options
Objecttype
String (optional) - Can be "none"
, "info"
, "error"
, "question"
or "warning"
. On Windows, "question"
displays the same icon as "info"
, unless you set an icon using the "icon"
option. On macOS, both "warning"
and "error"
display the same warning icon.buttons
String[] (optional) - Array of texts for buttons. On Windows, an empty array will result in one button labeled "OK".defaultId
Integer (optional) - Index of the button in the buttons array which will be selected by default when the message box opens.title
String (optional) - Title of the message box, some platforms will not show it.message
String - Content of the message box.detail
String (optional) - Extra information of the message.checkboxLabel
String (optional) - If provided, the message box will include a checkbox with the given label.checkboxChecked
Boolean (optional) - Initial checked state of the checkbox. false
by default.icon
NativeImage (optional)cancelId
Integer (optional) - The index of the button to be used to cancel the dialog, via the Esc
key. By default this is assigned to the first button with "cancel" or "no" as the label. If no such labeled buttons exist and this option is not set, 0
will be used as the return value.noLink
Boolean (optional) - On Windows Electron will try to figure out which one of the buttons
are common buttons (like "Cancel" or "Yes"), and show the others as command links in the dialog. This can make the dialog appear in the style of modern Windows apps. If you don't like this behavior, you can set noLink
to true
.normalizeAccessKeys
Boolean (optional) - Normalize the keyboard access keys across platforms. Default is false
. Enabling this assumes &
is used in the button labels for the placement of the keyboard shortcut access key and labels will be converted so they work correctly on each platform, &
characters are removed on macOS, converted to _
on Linux, and left untouched on Windows. For example, a button label of Vie&w
will be converted to Vie_w
on Linux and View
on macOS and can be selected via Alt-W
on Windows and Linux.Returns Promise<Object>
- resolves with a promise containing the following properties:
response
Number - The index of the clicked button.checkboxChecked
Boolean - The checked state of the checkbox if checkboxLabel
was set. Otherwise false
.Shows a message box, it will block the process until the message box is closed.
The browserWindow
argument allows the dialog to attach itself to a parent window, making it modal.
dialog.showErrorBox(title, content)
title
String - The title to display in the error box.content
String - The text content to display in the error box.Displays a modal dialog that shows an error message.
This API can be called safely before the ready
event the app
module emits, it is usually used to report errors in early stage of startup. If called before the app ready
event on Linux, the message will be emitted to stderr, and no GUI dialog will appear.
dialog.showCertificateTrustDialog([browserWindow, ]options)
macOS Windows
browserWindow
BrowserWindow (optional)options
Objectcertificate
Certificate - The certificate to trust/import.message
String - The message to display to the user.Returns Promise<void>
- resolves when the certificate trust dialog is shown.
On macOS, this displays a modal dialog that shows a message and certificate information, and gives the user the option of trusting/importing the certificate. If you provide a browserWindow
argument the dialog will be attached to the parent window, making it modal.
On Windows the options are more limited, due to the Win32 APIs used:
message
argument is not used, as the OS provides its own confirmation dialog.browserWindow
argument is ignored since it is not possible to make this confirmation dialog modal.showOpenDialog
, showOpenDialogSync
, showSaveDialog
, and showSaveDialogSync
will return a bookmarks
array.
Build Type | securityScopedBookmarks boolean | Return Type | Return Value |
---|---|---|---|
macOS mas | True | Success | ['LONGBOOKMARKSTRING'] |
macOS mas | True | Error |
[''] (array of empty string) |
macOS mas | False | NA |
[] (empty array) |
non mas | any | NA |
[] (empty array) |
On macOS, dialogs are presented as sheets attached to a window if you provide a BrowserWindow
reference in the browserWindow
parameter, or modals if no window is provided.
You can call BrowserWindow.getCurrentWindow().setSheetOffset(offset)
to change the offset from the window frame where sheets are attached.
id
Number - Unique identifier associated with the display.rotation
Number - Can be 0, 90, 180, 270, represents screen rotation in clock-wise degrees.scaleFactor
Number - Output device's pixel scale factor.touchSupport
String - Can be available
, unavailable
, unknown
.monochrome
Boolean - Whether or not the display is a monochrome display.accelerometerSupport
String - Can be available
, unavailable
, unknown
.colorSpace
String - represent a color space (three-dimensional object which contains all realizable color combinations) for the purpose of color conversionscolorDepth
Number - The number of bits per pixel.depthPerComponent
Number - The number of bits per color component.bounds
Rectangle
size
Size
workArea
Rectangle
workAreaSize
Size
internal
Boolean - true
for an internal display and false
for an external displayThe Display
object represents a physical display connected to the system. A fake Display
may exist on a headless system, or a Display
may correspond to a remote, virtual display.
Control your app in the macOS dock
Process: Main
The following example shows how to bounce your icon on the dock.
const { app } = require('electron') app.dock.bounce()
dock.bounce([type])
macOS
type
String (optional) - Can be critical
or informational
. The default is informational
Returns Integer
- an ID representing the request.
When critical
is passed, the dock icon will bounce until either the application becomes active or the request is canceled.
When informational
is passed, the dock icon will bounce for one second. However, the request remains active until either the application becomes active or the request is canceled.
Nota Bene: This method can only be used while the app is not focused; when the app is focused it will return -1.
dock.cancelBounce(id)
macOS
id
IntegerCancel the bounce of id
.
dock.downloadFinished(filePath)
macOS
filePath
StringBounces the Downloads stack if the filePath is inside the Downloads folder.
dock.setBadge(text)
macOS
text
StringSets the string to be displayed in the dock’s badging area.
dock.getBadge()
macOS
Returns String
- The badge string of the dock.
dock.hide()
macOS
Hides the dock icon.
dock.show()
macOS
Returns Promise<void>
- Resolves when the dock icon is shown.
dock.isVisible()
macOS
Returns Boolean
- Whether the dock icon is visible.
dock.setMenu(menu)
macOS
menu
Menu
Sets the application's [dock menu][dock-menu].
dock.getMenu()
macOS
Returns Menu | null
- The application's [dock menu][dock-menu].
dock.setIcon(image)
macOS
image
(NativeImage | String)Sets the image
associated with this dock icon.
Control file downloads from remote sources.
Process: Main
DownloadItem
is an EventEmitter that represents a download item in Electron. It is used in will-download
event of Session
class, and allows users to control the download item.
// In the main process. const { BrowserWindow } = require('electron') const win = new BrowserWindow() win.webContents.session.on('will-download', (event, item, webContents) => { // Set the save path, making Electron not to prompt a save dialog. item.setSavePath('/tmp/save.pdf') item.on('updated', (event, state) => { if (state === 'interrupted') { console.log('Download is interrupted but can be resumed') } else if (state === 'progressing') { if (item.isPaused()) { console.log('Download is paused') } else { console.log(`Received bytes: ${item.getReceivedBytes()}`) } } }) item.once('done', (event, state) => { if (state === 'completed') { console.log('Download successfully') } else { console.log(`Download failed: ${state}`) } }) })
Returns:
event
Eventstate
String - Can be progressing
or interrupted
.Emitted when the download has been updated and is not done.
The state
can be one of following:
progressing
- The download is in-progress.interrupted
- The download has interrupted and can be resumed.Returns:
event
Eventstate
String - Can be completed
, cancelled
or interrupted
.Emitted when the download is in a terminal state. This includes a completed download, a cancelled download (via downloadItem.cancel()
), and interrupted download that can't be resumed.
The state
can be one of following:
completed
- The download completed successfully.cancelled
- The download has been cancelled.interrupted
- The download has interrupted and can not resume.The downloadItem
object has the following methods:
downloadItem.setSavePath(path)
path
String - Set the save file path of the download item.The API is only available in session's will-download
callback function. If user doesn't set the save path via the API, Electron will use the original routine to determine the save path; this usually prompts a save dialog.
downloadItem.getSavePath()
Returns String
- The save path of the download item. This will be either the path set via downloadItem.setSavePath(path)
or the path selected from the shown save dialog.
downloadItem.setSaveDialogOptions(options)
options
SaveDialogOptions - Set the save file dialog options. This object has the same properties as the options
parameter of dialog.showSaveDialog()
.This API allows the user to set custom options for the save dialog that opens for the download item by default. The API is only available in session's will-download
callback function.
downloadItem.getSaveDialogOptions()
Returns SaveDialogOptions
- Returns the object previously set by downloadItem.setSaveDialogOptions(options)
.
downloadItem.pause()
Pauses the download.
downloadItem.isPaused()
Returns Boolean
- Whether the download is paused.
downloadItem.resume()
Resumes the download that has been paused.
Note: To enable resumable downloads the server you are downloading from must support range requests and provide both Last-Modified
and ETag
header values. Otherwise resume()
will dismiss previously received bytes and restart the download from the beginning.
downloadItem.canResume()
Returns Boolean
- Whether the download can resume.
downloadItem.cancel()
Cancels the download operation.
downloadItem.getURL()
Returns String
- The origin URL where the item is downloaded from.
downloadItem.getMimeType()
Returns String
- The files mime type.
downloadItem.hasUserGesture()
Returns Boolean
- Whether the download has user gesture.
downloadItem.getFilename()
Returns String
- The file name of the download item.
Note: The file name is not always the same as the actual one saved in local disk. If user changes the file name in a prompted download saving dialog, the actual name of saved file will be different.
downloadItem.getTotalBytes()
Returns Integer
- The total size in bytes of the download item.
If the size is unknown, it returns 0.
downloadItem.getReceivedBytes()
Returns Integer
- The received bytes of the download item.
downloadItem.getContentDisposition()
Returns String
- The Content-Disposition field from the response header.
downloadItem.getState()
Returns String
- The current state. Can be progressing
, completed
, cancelled
or interrupted
.
Note: The following methods are useful specifically to resume a cancelled
item when session is restarted.
downloadItem.getURLChain()
Returns String[]
- The complete URL chain of the item including any redirects.
downloadItem.getLastModifiedTime()
Returns String
- Last-Modified header value.
downloadItem.getETag()
Returns String
- ETag header value.
downloadItem.getStartTime()
Returns Double
- Number of seconds since the UNIX epoch when the download was started.
downloadItem.savePath
A String
property that determines the save file path of the download item.
The property is only available in session's will-download
callback function. If user doesn't set the save path via the property, Electron will use the original routine to determine the save path; this usually prompts a save dialog.
-beta.1
and stable
dates are our solid release dates.Version | -beta.1 | Stable | Chrome | Node |
---|---|---|---|---|
2.0.0 | 2018-02-21 | 2018-05-01 | M61 | v8.9 |
3.0.0 | 2018-06-21 | 2018-09-18 | M66 | v10.2 |
4.0.0 | 2018-10-11 | 2018-12-20 | M69 | v10.11 |
5.0.0 | 2019-01-22 | 2019-04-24 | M73 | v12.0 |
6.0.0 | 2019-05-01 | 2019-07-30 | M76 | v12.4 |
7.0.0 | 2019-08-01 | 2019-10-22 | M78 | v12.8 |
8.0.0 | 2019-10-24 | 2020-02-04 | M80 | v12.13 |
9.0.0 | 2020-02-06 | 2020-05-19 | M83 | v12.14 |
10.0.0 | 2020-05-21 | 2020-08-25 | M85 | v12.16 |
11.0.0 | 2020-08-27 | 2020-11-17 | M87 | v12.18 |
12.0.0 | 2020-11-19 | 2021-03-02 | M89 | v14.x |
A detailed look at our versioning policy and implementation.
As of version 2.0.0, Electron follows semver. The following command will install the most recent stable build of Electron:
npm install --save-dev electron
To update an existing project to use the latest stable version:
npm install --save-dev [email protected]
Electron versions < 2.0 did not conform to the semver spec: major versions corresponded to end-user API changes, minor versions corresponded to Chromium major releases, and patch versions corresponded to new features and bug fixes. While convenient for developers merging features, it creates problems for developers of client-facing applications. The QA testing cycles of major apps like Slack, Stride, Teams, Skype, VS Code, Atom, and Desktop can be lengthy and stability is a highly desired outcome. There is a high risk in adopting new features while trying to absorb bug fixes.
Here is an example of the 1.x strategy:
An app developed with 1.8.1
cannot take the 1.8.3
bug fix without either absorbing the 1.8.2
feature, or by backporting the fix and maintaining a new release line.
There are several major changes from our 1.x strategy outlined below. Each change is intended to satisfy the needs and priorities of developers/maintainers and app developers.
-beta
tagsmaster
branch is versionless; only stabilization branches contain version informationWe will cover in detail how git branching works, how npm tagging works, what developers should expect to see, and how one can backport changes.
From 2.0 onward, Electron will follow semver.
Below is a table explicitly mapping types of changes to their corresponding category of semver (e.g. Major, Minor, Patch).
Major Version Increments | Minor Version Increments | Patch Version Increments |
---|---|---|
Electron breaking API changes | Electron non-breaking API changes | Electron bug fixes |
Node.js major version updates | Node.js minor version updates | Node.js patch version updates |
Chromium version updates | fix-related chromium patches |
Note that most Chromium updates will be considered breaking. Fixes that can be backported will likely be cherry-picked as patches.
Stabilization branches are branches that run parallel to master, taking in only cherry-picked commits that are related to security or stability. These branches are never merged back to master.
Since Electron 8, stabilization branches are always major version lines, and named against the following template $MAJOR-x-y
e.g. 8-x-y
. Prior to that we used minor version lines and named them as $MAJOR-$MINOR-x
e.g. 2-0-x
We allow for multiple stabilization branches to exist simultaneously, and intend to support at least two in parallel at all times, backporting security fixes as necessary.
Older lines will not be supported by GitHub, but other groups can take ownership and backport stability and security fixes on their own. We discourage this, but recognize that it makes life easier for many app developers.
Developers want to know which releases are safe to use. Even seemingly innocent features can introduce regressions in complex applications. At the same time, locking to a fixed version is dangerous because you’re ignoring security patches and bug fixes that may have come out since your version. Our goal is to allow the following standard semver ranges in package.json
:
~2.0.0
to admit only stability or security related fixes to your 2.0.0
release.^2.0.0
to admit non-breaking reasonably stable feature work as well as security and bug fixes.What’s important about the second point is that apps using ^
should still be able to expect a reasonable level of stability. To accomplish this, semver allows for a pre-release identifier to indicate a particular version is not yet safe or stable.
Whatever you choose, you will periodically have to bump the version in your package.json
as breaking changes are a fact of Chromium life.
The process is as follows:
beta.N
, e.g. 2.0.0-beta.1
. After the first beta, subsequent beta releases must meet all of the following conditions:2.0.0-beta.2
.2.0.0
. After the first stable, all changes must be backwards-compatible bug or security fixes.2.0.1
.Specifically, the above means:
For each major and minor bump, you should expect to see something like the following:
2.0.0-beta.1 2.0.0-beta.2 2.0.0-beta.3 2.0.0 2.0.1 2.0.2
An example lifecycle in pictures:
2.0.0-beta.1
. 2.0.0-beta.2
. 2.0.0
. 2-0-x
line and release 2.0.1
. A few examples of how various semver ranges will pick up new releases:
Our strategy has a few tradeoffs, which for now we feel are appropriate. Most importantly that new features in master may take a while before reaching a stable release line. If you want to try a new feature immediately, you will have to build Electron yourself.
As a future consideration, we may introduce one or both of the following:
Feature flags are a common practice in Chromium, and are well-established in the web-development ecosystem. In the context of Electron, a feature flag or soft branch must have the following properties:
We seek to increase clarity at all levels of the update and releases process. Starting with 2.0.0
we will require pull requests adhere to the Conventional Commits spec, which can be summarized as follows:
Commits that would result in a semver major bump must start their body with BREAKING CHANGE:
.
Commits that would result in a semver minor bump must start with feat:
.
Commits that would result in a semver patch bump must start with fix:
.
We allow squashing of commits, provided that the squashed message adheres to the above message format.
It is acceptable for some commits in a pull request to not include a semantic prefix, as long as the pull request title contains a meaningful encompassing semantic message.
master
master
branch will always contain the next major version X.0.0-nightly.DATE
in its package.json
package.json
master
is always versioned as the next theoretical release branchLike NW.js, Electron provides a platform to write desktop applications with web technologies. Both platforms enable developers to utilize HTML, JavaScript, and Node.js. On the surface, they seem very similar.
There are however fundamental differences between the two projects that make Electron a completely separate product from NW.js.
In NW.js, the main entry point of an application can be an HTML web page. In that case, NW.js will open the given entry point in a browser window.
In Electron, the entry point is always a JavaScript script. Instead of providing a URL directly, you manually create a browser window and load an HTML file using the API. You also need to listen to window events to decide when to quit the application.
Electron works more like the Node.js runtime. Electron's APIs are lower level so you can use it for browser testing in place of PhantomJS.
In NW.js, the Node integration in web pages requires patching Chromium to work, while in Electron we chose a different way to integrate the libuv
loop with each platform's message loop to avoid hacking Chromium. See the node_bindings
code for how that was done.
If you are an experienced NW.js user, you should be familiar with the concept of Node context and web context. These concepts were invented because of how NW.js was implemented.
By using the multi-context feature of Node, Electron doesn't introduce a new JavaScript context in web pages.
Note: NW.js has optionally supported multi-context since 0.13.
NW.js still offers a "legacy release" that supports Windows XP. It doesn't receive security updates.
Given that hardware manufacturers, Microsoft, Chromium, and Node.js haven't released even critical security updates for that system, we have to warn you that using Windows XP is wildly insecure and outright irresponsible.
However, we understand that requirements outside our wildest imagination may exist, so if you're looking for something like Electron that runs on Windows XP, the NW.js legacy release might be the right fit for you.
There are numerous differences in the amount of supported features. Electron has a bigger community, more production apps using it, and a large amount of userland modules available on npm.
As an example, Electron has built-in support for automatic updates and countless tools that make the creation of installers easier. As an example in favor of NW.js, NW.js supports more Chrome.*
APIs for the development of Chrome Apps.
Naturally, we believe that Electron is the better platform for polished production applications built with web technologies (like Visual Studio Code, Slack, or Facebook Messenger); however, we want to be fair to our web technology friends. If you have feature needs that Electron does not meet, you might want to try NW.js.
Control application configuration and behavior without changing code.
Certain Electron behaviors are controlled by environment variables because they are initialized earlier than the command line flags and the app's code.
POSIX shell example:
$ export ELECTRON_ENABLE_LOGGING=true $ electron
Windows console example:
> set ELECTRON_ENABLE_LOGGING=true > electron
The following environment variables are intended primarily for use at runtime in packaged Electron applications.
NODE_OPTIONS
Electron includes support for a subset of Node's NODE_OPTIONS
. The majority are supported with the exception of those which conflict with Chromium's use of BoringSSL.
Example:
export NODE_OPTIONS="--no-warnings --max-old-space-size=2048"
Unsupported options are:
--use-bundled-ca --force-fips --enable-fips --openssl-config --use-openssl-ca
NODE_OPTIONS
are explicitly disallowed in packaged apps, except for the following:
--max-http-header-size --http-parser
GOOGLE_API_KEY
Geolocation support in Electron requires the use of Google Cloud Platform's geolocation webservice. To enable this feature, acquire a Google API key and place the following code in your main process file, before opening any browser windows that will make geolocation requests:
process.env.GOOGLE_API_KEY = 'YOUR_KEY_HERE'
By default, a newly generated Google API key may not be allowed to make geolocation requests. To enable the geolocation webservice for your project, enable it through the API library.
N.B. You will need to add a Billing Account to the project associated to the API key for the geolocation webservice to work.
ELECTRON_NO_ASAR
Disables ASAR support. This variable is only supported in forked child processes and spawned child processes that set ELECTRON_RUN_AS_NODE
.
ELECTRON_RUN_AS_NODE
Starts the process as a normal Node.js process.
In this mode, you will be able to pass cli options to Node.js as you would when running the normal Node.js executable, with the exception of the following flags:
These flags are disabled owing to the fact that Electron uses BoringSSL instead of OpenSSL when building Node.js' crypto
module, and so will not work as designed.
ELECTRON_NO_ATTACH_CONSOLE
Windows
Don't attach to the current console session.
ELECTRON_FORCE_WINDOW_MENU_BAR
Linux
Don't use the global menu bar on Linux.
ELECTRON_TRASH
Linux
Set the trash implementation on Linux. Default is gio
.
Options:
gvfs-trash
trash-cli
kioclient5
kioclient
The following environment variables are intended primarily for development and debugging purposes.
ELECTRON_ENABLE_LOGGING
Prints Chrome's internal logging to the console.
ELECTRON_LOG_ASAR_READS
When Electron reads from an ASAR file, log the read offset and file path to the system tmpdir
. The resulting file can be provided to the ASAR module to optimize file ordering.
ELECTRON_ENABLE_STACK_DUMPING
Prints the stack trace to the console when Electron crashes.
This environment variable will not work if the crashReporter
is started.
ELECTRON_DEFAULT_ERROR_MODE
Windows
Shows the Windows's crash dialog when Electron crashes.
This environment variable will not work if the crashReporter
is started.
ELECTRON_OVERRIDE_DIST_PATH
When running from the electron
package, this variable tells the electron
command to use the specified build of Electron instead of the one downloaded by npm install
. Usage:
export ELECTRON_OVERRIDE_DIST_PATH=/Users/username/projects/electron/out/Testing
Electron sets some variables in your environment at runtime.
ORIGINAL_XDG_CURRENT_DESKTOP
This variable is set to the value of XDG_CURRENT_DESKTOP
that your application originally launched with. Electron sometimes modifies the value of XDG_CURRENT_DESKTOP
to affect other logic within Chromium so if you want access to the original value you should look up this environment variable instead.
GlobalEvent
preventDefault
VoidFunctionSome of Electrons APIs are tagged with _Experimental_
in the documentation. This tag indicates that the API may not be considered stable and the API may be removed or modified more frequently than other APIs with less warning.
Anyone can request an API be tagged as experimental in a feature PR, disagreements on the experimental nature of a feature can be discussed in the API WG if they can't be resolved in the PR.
Once an API has been stable and in at least two major stable release lines it can be nominated to have its experimental tag removed. This discussion should happen at an API WG meeting. Things to consider when discussing / nominating:
id
Stringmanifest
any - Copy of the extension's manifest data.name
Stringpath
String - The extension's file path.version
Stringurl
String - The extension's chrome-extension://
URL.name
Stringversion
StringElectron supports a subset of the Chrome Extensions API, primarily to support DevTools extensions and Chromium-internal extensions, but it also happens to support some other extension capabilities.
Note: Electron does not support arbitrary Chrome extensions from the store, and it is a non-goal of the Electron project to be perfectly compatible with Chrome's implementation of Extensions.
Electron only supports loading unpacked extensions (i.e., .crx
files do not work). Extensions are installed per-session
. To load an extension, call ses.loadExtension
:
const { session } = require('electron') session.loadExtension('path/to/unpacked/extension').then(({ id }) => { // ... })
Loaded extensions will not be automatically remembered across exits; if you do not call loadExtension
when the app runs, the extension will not be loaded.
Note that loading extensions is only supported in persistent sessions. Attempting to load an extension into an in-memory session will throw an error.
See the session
documentation for more information about loading, unloading, and querying active extensions.
We support the following extensions APIs, with some caveats. Other APIs may additionally be supported, but support for any APIs not listed here is provisional and may be removed.
chrome.devtools.inspectedWindow
All features of this API are supported.
chrome.devtools.network
All features of this API are supported.
chrome.devtools.panels
All features of this API are supported.
chrome.extension
The following properties of chrome.extension
are supported:
chrome.extension.lastError
The following methods of chrome.extension
are supported:
chrome.extension.getURL
chrome.extension.getBackgroundPage
chrome.runtime
The following properties of chrome.runtime
are supported:
chrome.runtime.lastError
chrome.runtime.id
The following methods of chrome.runtime
are supported:
chrome.runtime.getBackgroundPage
chrome.runtime.getManifest
chrome.runtime.getURL
chrome.runtime.connect
chrome.runtime.sendMessage
The following events of chrome.runtime
are supported:
chrome.runtime.onStartup
chrome.runtime.onInstalled
chrome.runtime.onSuspend
chrome.runtime.onSuspendCanceled
chrome.runtime.onConnect
chrome.runtime.onMessage
chrome.storage
Only chrome.storage.local
is supported; chrome.storage.sync
and chrome.storage.managed
are not.
chrome.tabs
The following methods of chrome.tabs
are supported:
chrome.tabs.sendMessage
chrome.tabs.executeScript
Note: In Chrome, passing
-1
as a tab ID signifies the "currently active tab". Since Electron has no such concept, passing-1
as a tab ID is not supported and will raise an error.
chrome.management
The following methods of chrome.management
are supported:
chrome.management.getAll
chrome.management.get
chrome.management.getSelf
chrome.management.getPermissionWarningsById
chrome.management.getPermissionWarningsByManifest
chrome.management.onEnabled
chrome.management.onDisabled
When running npm install electron
, some users occasionally encounter installation errors.
In almost all cases, these errors are the result of network problems and not actual issues with the electron
npm package. Errors like ELIFECYCLE
, EAI_AGAIN
, ECONNRESET
, and ETIMEDOUT
are all indications of such network problems. The best resolution is to try switching networks, or wait a bit and try installing again.
You can also attempt to download Electron directly from electron/electron/releases if installing via npm
is failing.
The Chrome version of Electron is usually bumped within one or two weeks after a new stable Chrome version gets released. This estimate is not guaranteed and depends on the amount of work involved with upgrading.
Only the stable channel of Chrome is used. If an important fix is in beta or dev channel, we will back-port it.
For more information, please see the security introduction.
When a new version of Node.js gets released, we usually wait for about a month before upgrading the one in Electron. So we can avoid getting affected by bugs introduced in new Node.js versions, which happens very often.
New features of Node.js are usually brought by V8 upgrades, since Electron is using the V8 shipped by Chrome browser, the shiny new JavaScript feature of a new Node.js version is usually already in Electron.
To share data between web pages (the renderer processes) the simplest way is to use HTML5 APIs which are already available in browsers. Good candidates are Storage API, localStorage
, sessionStorage
, and IndexedDB.
Alternatively, you can use the IPC primitives that are provided by Electron. To share data between the main and renderer processes, you can use the ipcMain
and ipcRenderer
modules. To communicate directly between web pages, you can send a MessagePort
from one to the other, possibly via the main process using ipcRenderer.postMessage()
. Subsequent communication over message ports is direct and does not detour through the main process.
This happens when the variable which is used to store the tray gets garbage collected.
If you encounter this problem, the following articles may prove helpful:
If you want a quick fix, you can make the variables global by changing your code from this:
const { app, Tray } = require('electron') app.whenReady().then(() => { const tray = new Tray('/path/to/icon.png') tray.setTitle('hello world') })
to this:
const { app, Tray } = require('electron') let tray = null app.whenReady().then(() => { tray = new Tray('/path/to/icon.png') tray.setTitle('hello world') })
Due to the Node.js integration of Electron, there are some extra symbols inserted into the DOM like module
, exports
, require
. This causes problems for some libraries since they want to insert the symbols with the same names.
To solve this, you can turn off node integration in Electron:
// In the main process. const { BrowserWindow } = require('electron') const win = new BrowserWindow({ webPreferences: { nodeIntegration: false } }) win.show()
But if you want to keep the abilities of using Node.js and Electron APIs, you have to rename the symbols in the page before including other libraries:
<head> <script> window.nodeRequire = require; delete window.require; delete window.exports; delete window.module; </script> <script type="text/javascript" src="jquery.js"></script> </head>
require('electron').xxx
is undefined.When using Electron's built-in module you might encounter an error like this:
> require('electron').webFrame.setZoomFactor(1.0) Uncaught TypeError: Cannot read property 'setZoomLevel' of undefined
It is very likely you are using the module in the wrong process. For example electron.app
can only be used in the main process, while electron.webFrame
is only available in renderer processes.
If sub-pixel anti-aliasing is deactivated, then fonts on LCD screens can look blurry. Example:
Sub-pixel anti-aliasing needs a non-transparent background of the layer containing the font glyphs. (See this issue for more info).
To achieve this goal, set the background in the constructor for BrowserWindow:
const { BrowserWindow } = require('electron') const win = new BrowserWindow({ backgroundColor: '#fff' })
The effect is visible only on (some?) LCD screens. Even if you don't see a difference, some of your users may. It is best to always set the background this way, unless you have reasons not to do so.
Notice that just setting the background in the CSS does not have the desired effect.
name
Stringextensions
String[]File
ObjectUse the HTML5
File
API to work natively with files on the filesystem.
The DOM's File interface provides abstraction around native files in order to let users work on native files directly with the HTML5 file API. Electron has added a path
attribute to the File
interface which exposes the file's real path on filesystem.
Example of getting a real path from a dragged-onto-the-app file:
<div id="holder"> Drag your file here </div> <script> document.addEventListener('drop', (e) => { e.preventDefault(); e.stopPropagation(); for (const f of e.dataTransfer.files) { console.log('File(s) you dragged here: ', f.path) } }); document.addEventListener('dragover', (e) => { e.preventDefault(); e.stopPropagation(); }); </script>
path
String - The path to the file to send.headers
Record<string, string> (optional) - Additional headers to be sent.Open a window without toolbars, borders, or other graphical "chrome".
A frameless window is a window that has no chrome, the parts of the window, like toolbars, that are not a part of the web page. These are options on the BrowserWindow
class.
To create a frameless window, you need to set frame
to false
in BrowserWindow's options
:
const { BrowserWindow } = require('electron') const win = new BrowserWindow({ width: 800, height: 600, frame: false }) win.show()
There's an alternative way to specify a chromeless window. Instead of setting frame
to false
which disables both the titlebar and window controls, you may want to have the title bar hidden and your content extend to the full window size, yet still preserve the window controls ("traffic lights") for standard window actions. You can do so by specifying the titleBarStyle
option:
hidden
Results in a hidden title bar and a full size content window, yet the title bar still has the standard window controls (“traffic lights”) in the top left.
const { BrowserWindow } = require('electron') const win = new BrowserWindow({ titleBarStyle: 'hidden' }) win.show()
hiddenInset
Results in a hidden title bar with an alternative look where the traffic light buttons are slightly more inset from the window edge.
const { BrowserWindow } = require('electron') const win = new BrowserWindow({ titleBarStyle: 'hiddenInset' }) win.show()
customButtonsOnHover
Uses custom drawn close, and miniaturize buttons that display when hovering in the top left of the window. The fullscreen button is not available due to restrictions of frameless windows as they interface with Apple's macOS window masks. These custom buttons prevent issues with mouse events that occur with the standard window toolbar buttons. This option is only applicable for frameless windows.
const { BrowserWindow } = require('electron') const win = new BrowserWindow({ titleBarStyle: 'customButtonsOnHover', frame: false }) win.show()
By setting the transparent
option to true
, you can also make the frameless window transparent:
const { BrowserWindow } = require('electron') const win = new BrowserWindow({ transparent: true, frame: false }) win.show()
resizable
to true
may make a transparent window stop working on some platforms.blur
filter only applies to the web page, so there is no way to apply blur effect to the content below the window (i.e. other applications open on the user's system).--enable-transparent-visuals --disable-gpu
in the command line to disable GPU and allow ARGB to make transparent window, this is caused by an upstream bug that alpha channel doesn't work on some NVidia drivers on Linux.To create a click-through window, i.e. making the window ignore all mouse events, you can call the win.setIgnoreMouseEvents(ignore) API:
const { BrowserWindow } = require('electron') const win = new BrowserWindow() win.setIgnoreMouseEvents(true)
Ignoring mouse messages makes the web page oblivious to mouse movement, meaning that mouse movement events will not be emitted. On Windows operating systems an optional parameter can be used to forward mouse move messages to the web page, allowing events such as mouseleave
to be emitted:
const win = require('electron').remote.getCurrentWindow() const el = document.getElementById('clickThroughElement') el.addEventListener('mouseenter', () => { win.setIgnoreMouseEvents(true, { forward: true }) }) el.addEventListener('mouseleave', () => { win.setIgnoreMouseEvents(false) })
This makes the web page click-through when over el
, and returns to normal outside it.
By default, the frameless window is non-draggable. Apps need to specify -webkit-app-region: drag
in CSS to tell Electron which regions are draggable (like the OS's standard titlebar), and apps can also use -webkit-app-region: no-drag
to exclude the non-draggable area from the draggable region. Note that only rectangular shapes are currently supported.
Note: -webkit-app-region: drag
is known to have problems while the developer tools are open. See this GitHub issue for more information including a workaround.
To make the whole window draggable, you can add -webkit-app-region: drag
as body
's style:
<body style="-webkit-app-region: drag"> </body>
And note that if you have made the whole window draggable, you must also mark buttons as non-draggable, otherwise it would be impossible for users to click on them:
button { -webkit-app-region: no-drag; }
If you're only setting a custom titlebar as draggable, you also need to make all buttons in titlebar non-draggable.
In a frameless window the dragging behavior may conflict with selecting text. For example, when you drag the titlebar you may accidentally select the text on the titlebar. To prevent this, you need to disable text selection within a draggable area like this:
.titlebar { -webkit-user-select: none; -webkit-app-region: drag; }
On some platforms, the draggable area will be treated as a non-client frame, so when you right click on it a system menu will pop up. To make the context menu behave correctly on all platforms you should never use a custom context menu on draggable areas.
Package time feature toggles
For a subset of Electron functionality it makes sense to disable certain features for an entire application. For example, 99% of apps don't make use of ELECTRON_RUN_AS_NODE
, these applications want to be able to ship a binary that is incapable of using that feature. We also don't want Electron consumers building Electron from source as that is both a massive technical challenge and has a high cost of both time and money.
Fuses are the solution to this problem, at a high level they are "magic bits" in the Electron binary that can be flipped when packaging your Electron app to enable / disable certain features / restrictions. Because they are flipped at package time before you code sign your app the OS becomes responsible for ensuring those bits aren't flipped back via OS level code signing validation (Gatekeeper / App Locker).
We've made a handy module @electron/fuses
to make flipping these fuses easy. Check out the README of that module for more details on usage and potential error cases.
require('@electron/fuses').flipFuses( // Path to electron require('electron'), // Fuses to flip { runAsNode: false } )
Manually flipping fuses requires editing the Electron binary and modifying the fuse wire to be the sequence of bytes that represent the state of the fuses you want.
Somewhere in the Electron binary there will be a sequence of bytes that look like this:
| ...binary | sentinel_bytes | fuse_version | fuse_wire_length | fuse_wire | ...binary |
sentinel_bytes
is always this exact string dL7pKGdnNz796PbbjQWNKmHXBZaB9tsX
fuse_version
is a single byte whose unsigned integer value represents the version of the fuse schemafuse_wire_length
is a single byte whose unsigned integer value represents the number of fuses in the following fuse wirefuse_wire
is a sequence of N bytes, each byte represents a single fuse and its state.To flip a fuse you find its position in the fuse wire and change it to "0" or "1" depending on the state you'd like.
You can view the current schema here.
Detect keyboard events when the application does not have keyboard focus.
Process: Main
The globalShortcut
module can register/unregister a global keyboard shortcut with the operating system so that you can customize the operations for various shortcuts.
Note: The shortcut is global; it will work even if the app does not have the keyboard focus. You should not use this module until the ready
event of the app module is emitted.
const { app, globalShortcut } = require('electron') app.whenReady().then(() => { // Register a 'CommandOrControl+X' shortcut listener. const ret = globalShortcut.register('CommandOrControl+X', () => { console.log('CommandOrControl+X is pressed') }) if (!ret) { console.log('registration failed') } // Check whether a shortcut is registered. console.log(globalShortcut.isRegistered('CommandOrControl+X')) }) app.on('will-quit', () => { // Unregister a shortcut. globalShortcut.unregister('CommandOrControl+X') // Unregister all shortcuts. globalShortcut.unregisterAll() })
The globalShortcut
module has the following methods:
globalShortcut.register(accelerator, callback)
accelerator
Accelerator
callback
FunctionReturns Boolean
- Whether or not the shortcut was registered successfully.
Registers a global shortcut of accelerator
. The callback
is called when the registered shortcut is pressed by the user.
When the accelerator is already taken by other applications, this call will silently fail. This behavior is intended by operating systems, since they don't want applications to fight for global shortcuts.
The following accelerators will not be registered successfully on macOS 10.14 Mojave unless the app has been authorized as a trusted accessibility client:
globalShortcut.registerAll(accelerators, callback)
accelerators
String[] - an array of Accelerators.callback
FunctionRegisters a global shortcut of all accelerator
items in accelerators
. The callback
is called when any of the registered shortcuts are pressed by the user.
When a given accelerator is already taken by other applications, this call will silently fail. This behavior is intended by operating systems, since they don't want applications to fight for global shortcuts.
The following accelerators will not be registered successfully on macOS 10.14 Mojave unless the app has been authorized as a trusted accessibility client:
globalShortcut.isRegistered(accelerator)
accelerator
Accelerator
Returns Boolean
- Whether this application has registered accelerator
.
When the accelerator is already taken by other applications, this call will still return false
. This behavior is intended by operating systems, since they don't want applications to fight for global shortcuts.
globalShortcut.unregister(accelerator)
accelerator
Accelerator
Unregisters the global shortcut of accelerator
.
globalShortcut.unregisterAll()
Unregisters all of the global shortcuts.
This page defines some terminology that is commonly used in Electron development.
ASAR stands for Atom Shell Archive Format. An asar archive is a simple tar
-like format that concatenates files into a single file. Electron can read arbitrary files from it without unpacking the whole file.
The ASAR format was created primarily to improve performance on Windows... TODO
The C Run-time Library (CRT) is the part of the C++ Standard Library that incorporates the ISO C99 standard library. The Visual C++ libraries that implement the CRT support native code development, and both mixed native and managed code, and pure managed code for .NET development.
An Apple Disk Image is a packaging format used by macOS. DMG files are commonly used for distributing application "installers". electron-builder supports dmg
as a build target.
Input Method Editor. A program that allows users to enter characters and symbols not found on their keyboard. For example, this allows users of Latin keyboards to input Chinese, Japanese, Korean and Indic characters.
Interface description language. Write function signatures and data types in a format that can be used to generate interfaces in Java, C++, JavaScript, etc.
IPC stands for Inter-Process Communication. Electron uses IPC to send serialized JSON messages between the main and renderer processes.
A shared library that includes the Chromium Content module and all its dependencies (e.g., Blink, V8, etc.). Also referred to as "libcc".
The main process, commonly a file named main.js
, is the entry point to every Electron app. It controls the life of the app, from open to close. It also manages native elements such as the Menu, Menu Bar, Dock, Tray, etc. The main process is responsible for creating each new renderer process in the app. The full Node API is built in.
Every app's main process file is specified in the main
property in package.json
. This is how electron .
knows what file to execute at startup.
In Chromium, this process is referred to as the "browser process". It is renamed in Electron to avoid confusion with renderer processes.
See also: process, renderer process
Acronym for Apple's Mac App Store. For details on submitting your app to the MAS, see the Mac App Store Submission Guide.
An IPC system for communicating intra- or inter-process, and that's important because Chrome is keen on being able to split its work into separate processes or not, depending on memory pressures etc.
See https://chromium.googlesource.com/chromium/src/+/master/mojo/README.md
Native modules (also called addons in Node.js) are modules written in C or C++ that can be loaded into Node.js or Electron using the require() function, and used as if they were an ordinary Node.js module. They are used primarily to provide an interface between JavaScript running in Node.js and C/C++ libraries.
Native Node modules are supported by Electron, but since Electron is very likely to use a different V8 version from the Node binary installed in your system, you have to manually specify the location of Electron’s headers when building native modules.
See also Using Native Node Modules.
Nullsoft Scriptable Install System is a script-driven Installer authoring tool for Microsoft Windows. It is released under a combination of free software licenses, and is a widely-used alternative to commercial proprietary products like InstallShield. electron-builder supports NSIS as a build target.
OSR (Off-screen rendering) can be used for loading heavy page in background and then displaying it after (it will be much faster). It allows you to render page without showing it on screen.
A process is an instance of a computer program that is being executed. Electron apps that make use of the main and one or many renderer process are actually running several programs simultaneously.
In Node.js and Electron, each running process has a process
object. This object is a global that provides information about, and control over, the current process. As a global, it is always available to applications without using require().
See also: main process, renderer process
The renderer process is a browser window in your app. Unlike the main process, there can be multiple of these and each is run in a separate process. They can also be hidden.
In normal browsers, web pages usually run in a sandboxed environment and are not allowed access to native resources. Electron users, however, have the power to use Node.js APIs in web pages allowing lower level operating system interactions.
See also: process, main process
Squirrel is an open-source framework that enables Electron apps to update automatically as new versions are released. See the autoUpdater API for info about getting started with Squirrel.
This term originated in the Unix community, where "userland" or "userspace" referred to programs that run outside of the operating system kernel. More recently, the term has been popularized in the Node and npm community to distinguish between the features available in "Node core" versus packages published to the npm registry by the much larger "user" community.
Like Node, Electron is focused on having a small set of APIs that provide all the necessary primitives for developing multi-platform desktop applications. This design philosophy allows Electron to remain a flexible tool without being overly prescriptive about how it should be used. Userland enables users to create and share tools that provide additional functionality on top of what is available in "core".
V8 is Google's open source JavaScript engine. It is written in C++ and is used in Google Chrome. V8 can run standalone, or can be embedded into any C++ application.
Electron builds V8 as part of Chromium and then points Node to that V8 when building it.
V8's version numbers always correspond to those of Google Chrome. Chrome 59 includes V8 5.9, Chrome 58 includes V8 5.8, etc.
webview
tags are used to embed 'guest' content (such as external web pages) in your Electron app. They are similar to iframe
s, but differ in that each webview runs in a separate process. It doesn't have the same permissions as your web page and all interactions between your app and embedded content will be asynchronous. This keeps your app safe from the embedded content.
Goma is a distributed compiler service for open-source projects such as Chromium and Android.
Electron has a deployment of a custom Goma Backend that we make available to all Electron Maintainers. See the Access section below for details on authentication. There is also a cache-only
Goma endpoint that will be used by default if you do not have credentials. Requests to the cache-only Goma will not hit our cluster, but will read from our cache and should result in significantly faster build times.
Currently the only supported way to use Goma is to use our Build Tools. Goma configuration is automatically included when you set up build-tools
.
If you are a maintainer and have access to our cluster, please ensure that you run e init
with --goma=cluster
in order to configure build-tools
to use the Goma cluster. If you have an existing config, you can just set "goma": "cluster"
in your config file.
When you are using Goma you can run ninja
with a substantially higher j
value than would normally be supported by your machine.
Please do not set a value higher than 200 on Windows or Linux and 50 on macOS. We monitor Goma system usage, and users found to be abusing it with unreasonable concurrency will be de-activated.
ninja -C out/Testing electron -j 200
If you're using build-tools
, appropriate -j
values will automatically be used for you.
If you access http://localhost:8088 on your local machine you can monitor compile jobs as they flow through the goma system.
For security and cost reasons, access to Electron's Goma cluster is currently restricted to Electron Maintainers. If you want access please head to #access-requests
in Slack and ping @goma-squad
to ask for access. Please be aware that being a maintainer does not automatically grant access and access is determined on a case by case basis.
We have automated monitoring of our Goma cluster and cache at https://status.notgoma.com
We do not provide support for usage of Goma and any issues raised asking for help / having issues will probably be closed without much reason, we do not have the capacity to handle that kind of support.
2d_canvas
String - Canvas.flash_3d
String - Flash.flash_stage3d
String - Flash Stage3D.flash_stage3d_baseline
String - Flash Stage3D Baseline profile.gpu_compositing
String - Compositing.multiple_raster_threads
String - Multiple Raster Threads.native_gpu_memory_buffers
String - Native GpuMemoryBuffers.rasterization
String - Rasterization.video_decode
String - Video Decode.video_encode
String - Video Encode.vpx_decode
String - VPx Video Decode.webgl
String - WebGL.webgl2
String - WebGL2.Possible values:
disabled_software
- Software only. Hardware acceleration disabled (yellow)disabled_off
- Disabled (red)disabled_off_ok
- Disabled (yellow)unavailable_software
- Software only, hardware acceleration unavailable (yellow)unavailable_off
- Unavailable (red)unavailable_off_ok
- Unavailable (yellow)enabled_readback
- Hardware accelerated but at reduced performance (yellow)enabled_force
- Hardware accelerated on all pages (green)enabled
- Hardware accelerated (green)enabled_on
- Enabled (green)enabled_force_on
- Force enabled (green)In-app purchases on Mac App Store.
Process: Main
The inAppPurchase
module emits the following events:
Emitted when one or more transactions have been updated.
Returns:
event
Eventtransactions
Transaction[] - Array of Transaction
objects.The inAppPurchase
module has the following methods:
inAppPurchase.purchaseProduct(productID[, quantity])
productID
String - The identifiers of the product to purchase. (The identifier of com.example.app.product1
is product1
).quantity
Integer (optional) - The number of items the user wants to purchase.Returns Promise<Boolean>
- Returns true
if the product is valid and added to the payment queue.
You should listen for the transactions-updated
event as soon as possible and certainly before you call purchaseProduct
.
inAppPurchase.getProducts(productIDs)
productIDs
String[] - The identifiers of the products to get.Returns Promise<Product[]>
- Resolves with an array of Product
objects.
Retrieves the product descriptions.
inAppPurchase.canMakePayments()
Returns Boolean
- whether a user can make a payment.
inAppPurchase.restoreCompletedTransactions()
Restores finished transactions. This method can be called either to install purchases on additional devices, or to restore purchases for an application that the user deleted and reinstalled.
The payment queue delivers a new transaction for each previously completed transaction that can be restored. Each transaction includes a copy of the original transaction.
inAppPurchase.getReceiptURL()
Returns String
- the path to the receipt.
inAppPurchase.finishAllTransactions()
Completes all pending transactions.
inAppPurchase.finishTransactionByDate(date)
date
String - The ISO formatted date of the transaction to finish.Completes the pending transactions corresponding to the date.
If you haven't already, you’ll need to sign the Paid Applications Agreement and set up your banking and tax information in iTunes Connect.
iTunes Connect Developer Help: Agreements, tax, and banking overview
Then, you'll need to configure your in-app purchases in iTunes Connect, and include details such as name, pricing, and description that highlights the features and functionality of your in-app purchase.
iTunes Connect Developer Help: Create an in-app purchase
To test In-App Purchase in development with Electron you'll have to change the CFBundleIdentifier
in node_modules/electron/dist/Electron.app/Contents/Info.plist
. You have to replace com.github.electron
by the bundle identifier of the application you created with iTunes Connect.
<key>CFBundleIdentifier</key> <string>com.example.app</string>
Here is an example that shows how to use In-App Purchases in Electron. You'll have to replace the product ids by the identifiers of the products created with iTunes Connect (the identifier of com.example.app.product1
is product1
). Note that you have to listen to the transactions-updated
event as soon as possible in your app.
// Main process const { inAppPurchase } = require('electron') const PRODUCT_IDS = ['id1', 'id2'] // Listen for transactions as soon as possible. inAppPurchase.on('transactions-updated', (event, transactions) => { if (!Array.isArray(transactions)) { return } // Check each transaction. transactions.forEach(function (transaction) { const payment = transaction.payment switch (transaction.transactionState) { case 'purchasing': console.log(`Purchasing ${payment.productIdentifier}...`) break case 'purchased': { console.log(`${payment.productIdentifier} purchased.`) // Get the receipt url. const receiptURL = inAppPurchase.getReceiptURL() console.log(`Receipt URL: ${receiptURL}`) // Submit the receipt file to the server and check if it is valid. // @see https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html // ... // If the receipt is valid, the product is purchased // ... // Finish the transaction. inAppPurchase.finishTransactionByDate(transaction.transactionDate) break } case 'failed': console.log(`Failed to purchase ${payment.productIdentifier}.`) // Finish the transaction. inAppPurchase.finishTransactionByDate(transaction.transactionDate) break case 'restored': console.log(`The purchase of ${payment.productIdentifier} has been restored.`) break case 'deferred': console.log(`The purchase of ${payment.productIdentifier} has been deferred.`) break default: break } }) }) // Check if the user is allowed to make in-app purchase. if (!inAppPurchase.canMakePayments()) { console.log('The user is not allowed to make in-app purchase.') } // Retrieve and display the product descriptions. inAppPurchase.getProducts(PRODUCT_IDS).then(products => { // Check the parameters. if (!Array.isArray(products) || products.length <= 0) { console.log('Unable to retrieve the product informations.') return } // Display the name and price of each product. products.forEach(product => { console.log(`The price of ${product.localizedTitle} is ${product.formattedPrice}.`) }) // Ask the user which product he/she wants to purchase. const selectedProduct = products[0] const selectedQuantity = 1 // Purchase the selected product. inAppPurchase.purchaseProduct(selectedProduct.productIdentifier, selectedQuantity).then(isProductValid => { if (!isProductValid) { console.log('The product is not valid.') return } console.log('The payment has been added to the payment queue.') }) })
Handle responses to HTTP/HTTPS requests.
Process: Main
IncomingMessage
implements the Readable Stream interface and is therefore an EventEmitter.
Returns:
chunk
Buffer - A chunk of response body's data.The data
event is the usual method of transferring response data into applicative code.
Indicates that response body has ended.
Emitted when a request has been canceled during an ongoing HTTP transaction.
Returns:
error
Error - Typically holds an error string identifying failure root cause.
Emitted when an error was encountered while streaming response data events. For instance, if the server closes the underlying while the response is still streaming, an error
event will be emitted on the response object and a close
event will subsequently follow on the request object.
An IncomingMessage
instance has the following readable properties:
response.statusCode
An Integer
indicating the HTTP response status code.
response.statusMessage
A String
representing the HTTP status message.
response.headers
A Record<string, string | string[]>
representing the HTTP response headers. The headers
object is formatted as follows:
age
, authorization
, content-length
, content-type
, etag
, expires
, from
, host
, if-modified-since
, if-unmodified-since
, last-modified
, location
, max-forwards
, proxy-authorization
, referer
, retry-after
, server
, or user-agent
are discarded.set-cookie
is always an array. Duplicates are added to the array.cookie
headers, the values are joined together with '; '.response.httpVersion
A String
indicating the HTTP protocol version number. Typical values are '1.0' or '1.1'. Additionally httpVersionMajor
and httpVersionMinor
are two Integer-valued readable properties that return respectively the HTTP major and minor version numbers.
response.httpVersionMajor
An Integer
indicating the HTTP protocol major version number.
response.httpVersionMinor
An Integer
indicating the HTTP protocol minor version number.
modifiers
String[] (optional) - An array of modifiers of the event, can be shift
, control
, ctrl
, alt
, meta
, command
, cmd
, isKeypad
, isAutoRepeat
, leftButtonDown
, middleButtonDown
, rightButtonDown
, capsLock
, numLock
, left
, right
.To install prebuilt Electron binaries, use npm
. The preferred method is to install Electron as a development dependency in your app:
npm install electron --save-dev
See the Electron versioning doc for info on how to manage Electron versions in your apps.
You can also install the electron
command globally in your $PATH
:
npm install electron -g
If you want to change the architecture that is downloaded (e.g., ia32
on an x64
machine), you can use the --arch
flag with npm install or set the npm_config_arch
environment variable:
npm install --arch=ia32 electron
In addition to changing the architecture, you can also specify the platform (e.g., win32
, linux
, etc.) using the --platform
flag:
npm install --platform=win32 electron
If you need to use an HTTP proxy, you need to set the ELECTRON_GET_USE_PROXY
variable to any value, plus additional environment variables depending on your host system's Node version:
During installation, the electron
module will call out to @electron/get
to download prebuilt binaries of Electron for your platform. It will do so by contacting GitHub's release download page (https://github.com/electron/electron/releases/tag/v$VERSION
, where $VERSION
is the exact version of Electron).
If you are unable to access GitHub or you need to provide a custom build, you can do so by either providing a mirror or an existing cache directory.
You can use environment variables to override the base URL, the path at which to look for Electron binaries, and the binary filename. The URL used by @electron/get
is composed as follows:
url = ELECTRON_MIRROR + ELECTRON_CUSTOM_DIR + '/' + ELECTRON_CUSTOM_FILENAME
For instance, to use the China CDN mirror:
ELECTRON_MIRROR="https://cdn.npm.taobao.org/dist/electron/"
By default, ELECTRON_CUSTOM_DIR
is set to v$VERSION
. To change the format, use the {{ version }}
placeholder. For example, version-{{ version }}
resolves to version-5.0.0
, {{ version }}
resolves to 5.0.0
, and v{{ version }}
is equivalent to the default. As a more concrete example, to use the China non-CDN mirror:
ELECTRON_MIRROR="https://npm.taobao.org/mirrors/electron/" ELECTRON_CUSTOM_DIR="{{ version }}"
The above configuration will download from URLs such as https://npm.taobao.org/mirrors/electron/8.0.0/electron-v8.0.0-linux-x64.zip
.
Alternatively, you can override the local cache. @electron/get
will cache downloaded binaries in a local directory to not stress your network. You can use that cache folder to provide custom builds of Electron or to avoid making contact with the network at all.
$XDG_CACHE_HOME
or ~/.cache/electron/
~/Library/Caches/electron/
$LOCALAPPDATA/electron/Cache
or ~/AppData/Local/electron/Cache/
On environments that have been using older versions of Electron, you might find the cache also in ~/.electron
.
You can also override the local cache location by providing a electron_config_cache
environment variable.
The cache contains the version's official zip file as well as a checksum, stored as a text file. A typical cache might look like this:
├── httpsgithub.comelectronelectronreleasesdownloadv1.7.9electron-v1.7.9-darwin-x64.zip │ └── electron-v1.7.9-darwin-x64.zip ├── httpsgithub.comelectronelectronreleasesdownloadv1.7.9SHASUMS256.txt │ └── SHASUMS256.txt ├── httpsgithub.comelectronelectronreleasesdownloadv1.8.1electron-v1.8.1-darwin-x64.zip │ └── electron-v1.8.1-darwin-x64.zip ├── httpsgithub.comelectronelectronreleasesdownloadv1.8.1SHASUMS256.txt │ └── SHASUMS256.txt ├── httpsgithub.comelectronelectronreleasesdownloadv1.8.2-beta.1electron-v1.8.2-beta.1-darwin-x64.zip │ └── electron-v1.8.2-beta.1-darwin-x64.zip ├── httpsgithub.comelectronelectronreleasesdownloadv1.8.2-beta.1SHASUMS256.txt │ └── SHASUMS256.txt ├── httpsgithub.comelectronelectronreleasesdownloadv1.8.2-beta.2electron-v1.8.2-beta.2-darwin-x64.zip │ └── electron-v1.8.2-beta.2-darwin-x64.zip ├── httpsgithub.comelectronelectronreleasesdownloadv1.8.2-beta.2SHASUMS256.txt │ └── SHASUMS256.txt ├── httpsgithub.comelectronelectronreleasesdownloadv1.8.2-beta.3electron-v1.8.2-beta.3-darwin-x64.zip │ └── electron-v1.8.2-beta.3-darwin-x64.zip └── httpsgithub.comelectronelectronreleasesdownloadv1.8.2-beta.3SHASUMS256.txt └── SHASUMS256.txt
When installing the electron
NPM package, it automatically downloads the electron binary.
This can sometimes be unnecessary, e.g. in a CI environment, when testing another component.
To prevent the binary from being downloaded when you install all npm dependencies you can set the environment variable ELECTRON_SKIP_BINARY_DOWNLOAD
. E.g.:
ELECTRON_SKIP_BINARY_DOWNLOAD=1 npm install
When running npm install electron
, some users occasionally encounter installation errors.
In almost all cases, these errors are the result of network problems and not actual issues with the electron
npm package. Errors like ELIFECYCLE
, EAI_AGAIN
, ECONNRESET
, and ETIMEDOUT
are all indications of such network problems. The best resolution is to try switching networks, or wait a bit and try installing again.
You can also attempt to download Electron directly from electron/electron/releases if installing via npm
is failing.
If installation fails with an EACCESS
error you may need to fix your npm permissions.
If the above error persists, the unsafe-perm flag may need to be set to true:
sudo npm install electron --unsafe-perm=true
On slower networks, it may be advisable to use the --verbose
flag in order to show download progress:
npm install --verbose electron
If you need to force a re-download of the asset and the SHASUM file set the force_no_cache
environment variable to true
.
readOperationCount
Number - The number of I/O read operations.writeOperationCount
Number - The number of I/O write operations.otherOperationCount
Number - Then number of I/O other operations.readTransferCount
Number - The number of I/O read transfers.writeTransferCount
Number - The number of I/O write transfers.otherTransferCount
Number - Then number of I/O other transfers.Communicate asynchronously from the main process to renderer processes.
Process: Main
The ipcMain
module is an Event Emitter. When used in the main process, it handles asynchronous and synchronous messages sent from a renderer process (web page). Messages sent from a renderer will be emitted to this module.
It is also possible to send messages from the main process to the renderer process, see webContents.send for more information.
channel
.event.returnValue
.event.reply(...)
. This helper method will automatically handle messages coming from frames that aren't the main frame (e.g. iframes) whereas event.sender.send(...)
will always send to the main frame.An example of sending and handling messages between the render and main processes:
// In main process. const { ipcMain } = require('electron') ipcMain.on('asynchronous-message', (event, arg) => { console.log(arg) // prints "ping" event.reply('asynchronous-reply', 'pong') }) ipcMain.on('synchronous-message', (event, arg) => { console.log(arg) // prints "ping" event.returnValue = 'pong' })
// In renderer process (web page). const { ipcRenderer } = require('electron') console.log(ipcRenderer.sendSync('synchronous-message', 'ping')) // prints "pong" ipcRenderer.on('asynchronous-reply', (event, arg) => { console.log(arg) // prints "pong" }) ipcRenderer.send('asynchronous-message', 'ping')
The ipcMain
module has the following method to listen for events:
ipcMain.on(channel, listener)
channel
Stringlistener
Functionevent
IpcMainEvent...args
any[]Listens to channel
, when a new message arrives listener
would be called with listener(event, args...)
.
ipcMain.once(channel, listener)
channel
Stringlistener
Functionevent
IpcMainEvent...args
any[]Adds a one time listener
function for the event. This listener
is invoked only the next time a message is sent to channel
, after which it is removed.
ipcMain.removeListener(channel, listener)
channel
Stringlistener
Function...args
any[]Removes the specified listener
from the listener array for the specified channel
.
ipcMain.removeAllListeners([channel])
channel
String (optional)Removes listeners of the specified channel
.
ipcMain.handle(channel, listener)
channel
Stringlistener
Function<Promise\event
IpcMainInvokeEvent...args
any[]Adds a handler for an invoke
able IPC. This handler will be called whenever a renderer calls ipcRenderer.invoke(channel, ...args)
.
If listener
returns a Promise, the eventual result of the promise will be returned as a reply to the remote caller. Otherwise, the return value of the listener will be used as the value of the reply.
// Main process ipcMain.handle('my-invokable-ipc', async (event, ...args) => { const result = await somePromise(...args) return result }) // Renderer process async () => { const result = await ipcRenderer.invoke('my-invokable-ipc', arg1, arg2) // ... }
The event
that is passed as the first argument to the handler is the same as that passed to a regular event listener. It includes information about which WebContents is the source of the invoke request.
ipcMain.handleOnce(channel, listener)
channel
Stringlistener
Function<Promise\event
IpcMainInvokeEvent...args
any[]Handles a single invoke
able IPC message, then removes the listener. See ipcMain.handle(channel, listener)
.
ipcMain.removeHandler(channel)
channel
StringRemoves any handler for channel
, if present.
The documentation for the event
object passed to the callback
can be found in the ipc-main-event
structure docs.
The documentation for the event
object passed to handle
callbacks can be found in the ipc-main-invoke-event
structure docs.
Event
frameId
Integer - The ID of the renderer frame that sent this messagereturnValue
any - Set this to the value to be returned in a synchronous messagesender
WebContents - Returns the webContents
that sent the messageports
MessagePortMain[] - A list of MessagePorts that were transferred with this messagereply
Function - A function that will send an IPC message to the renderer frame that sent the original message that you are currently handling. You should use this method to "reply" to the sent message in order to guarantee the reply will go to the correct process and frame.channel
String...args
any[]Event
frameId
Integer - The ID of the renderer frame that sent this messagesender
WebContents - Returns the webContents
that sent the messageCommunicate asynchronously from a renderer process to the main process.
Process: Renderer
The ipcRenderer
module is an EventEmitter. It provides a few methods so you can send synchronous and asynchronous messages from the render process (web page) to the main process. You can also receive replies from the main process.
See ipcMain for code examples.
The ipcRenderer
module has the following method to listen for events and send messages:
ipcRenderer.on(channel, listener)
channel
Stringlistener
Functionevent
IpcRendererEvent...args
any[]Listens to channel
, when a new message arrives listener
would be called with listener(event, args...)
.
ipcRenderer.once(channel, listener)
channel
Stringlistener
Functionevent
IpcRendererEvent...args
any[]Adds a one time listener
function for the event. This listener
is invoked only the next time a message is sent to channel
, after which it is removed.
ipcRenderer.removeListener(channel, listener)
channel
Stringlistener
Function...args
any[]Removes the specified listener
from the listener array for the specified channel
.
ipcRenderer.removeAllListeners(channel)
channel
StringRemoves all listeners, or those of the specified channel
.
ipcRenderer.send(channel, ...args)
channel
String...args
any[]Send an asynchronous message to the main process via channel
, along with arguments. Arguments will be serialized with the Structured Clone Algorithm, just like window.postMessage
, so prototype chains will not be included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will throw an exception.
NOTE: Sending non-standard JavaScript types such as DOM objects or special Electron objects is deprecated, and will begin throwing an exception starting with Electron 9.
The main process handles it by listening for channel
with the ipcMain
module.
If you need to transfer a MessagePort
to the main process, use ipcRenderer.postMessage
.
If you want to receive a single response from the main process, like the result of a method call, consider using ipcRenderer.invoke
.
ipcRenderer.invoke(channel, ...args)
channel
String...args
any[]Returns Promise<any>
- Resolves with the response from the main process.
Send a message to the main process via channel
and expect a result asynchronously. Arguments will be serialized with the Structured Clone Algorithm, just like window.postMessage
, so prototype chains will not be included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will throw an exception.
NOTE: Sending non-standard JavaScript types such as DOM objects or special Electron objects is deprecated, and will begin throwing an exception starting with Electron 9.
The main process should listen for channel
with ipcMain.handle()
.
For example:
// Renderer process ipcRenderer.invoke('some-name', someArgument).then((result) => { // ... }) // Main process ipcMain.handle('some-name', async (event, someArgument) => { const result = await doSomeWork(someArgument) return result })
If you need to transfer a MessagePort
to the main process, use ipcRenderer.postMessage
.
If you do not need a response to the message, consider using ipcRenderer.send
.
ipcRenderer.sendSync(channel, ...args)
channel
String...args
any[]Returns any
- The value sent back by the ipcMain
handler.
Send a message to the main process via channel
and expect a result synchronously. Arguments will be serialized with the Structured Clone Algorithm, just like window.postMessage
, so prototype chains will not be included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will throw an exception.
NOTE: Sending non-standard JavaScript types such as DOM objects or special Electron objects is deprecated, and will begin throwing an exception starting with Electron 9.
The main process handles it by listening for channel
with ipcMain
module, and replies by setting event.returnValue
.
⚠️ WARNING: Sending a synchronous message will block the whole renderer process until the reply is received, so use this method only as a last resort. It's much better to use the asynchronous version,
invoke()
.
ipcRenderer.postMessage(channel, message, [transfer])
channel
Stringmessage
anytransfer
MessagePort[] (optional)Send a message to the main process, optionally transferring ownership of zero or more MessagePort
objects.
The transferred MessagePort
objects will be available in the main process as MessagePortMain
objects by accessing the ports
property of the emitted event.
For example:
// Renderer process const { port1, port2 } = new MessageChannel() ipcRenderer.postMessage('port', { message: 'hello' }, [port1]) // Main process ipcMain.on('port', (e, msg) => { const [port] = e.ports // ... })
For more information on using MessagePort
and MessageChannel
, see the MDN documentation.
ipcRenderer.sendTo(webContentsId, channel, ...args)
webContentsId
Numberchannel
String...args
any[]Sends a message to a window with webContentsId
via channel
.
ipcRenderer.sendToHost(channel, ...args)
channel
String...args
any[]Like ipcRenderer.send
but the event will be sent to the <webview>
element in the host page instead of the main process.
The documentation for the event
object passed to the callback
can be found in the ipc-renderer-event
structure docs.
Event
sender
IpcRenderer - The IpcRenderer
instance that emitted the event originallysenderId
Integer - The webContents.id
that sent the message, you can call event.sender.sendTo(event.senderId, ...)
to reply to the message, see ipcRenderer.sendTo for more information. This only applies to messages sent from a different renderer. Messages sent directly from the main process set event.senderId
to 0
.ports
MessagePort[] - A list of MessagePorts that were transferred with this messageFor any issue, there are fundamentally three ways an individual can contribute:
electron/electron
issue tracker.electron/electron
in a concrete and reviewable manner."Finding Support" has a list of resources for getting programming help, reporting security issues, contributing, and more. Please use the issue tracker for bugs only!
To submit a bug report:
When opening a new issue in the electron/electron
issue tracker, users will be presented with a template that should be filled in.
If you believe that you have found a bug in Electron, please fill out the template to the best of your ability.
The two most important pieces of information needed to evaluate the report are a description of the bug and a simple test case to recreate it. It is easier to fix a bug if it can be reproduced.
See How to create a Minimal, Complete, and Verifiable example.
It's common for open issues to involve discussion. Some contributors may have differing opinions, including whether the behavior is a bug or feature. This discussion is part of the process and should be kept focused, helpful, and professional.
Terse responses that provide neither additional context nor supporting detail are not helpful or professional. To many, such responses are annoying and unfriendly.
Contributors are encouraged to solve issues collaboratively and help one another make progress. If you encounter an issue that you feel is invalid, or which contains incorrect information, explain why you feel that way with additional supporting context, and be willing to be convinced that you may be wrong. By doing so, we can often reach the correct outcome faster.
Most issues are resolved by opening a pull request. The process for opening and reviewing a pull request is similar to that of opening and triaging issues, but carries with it a necessary review and approval workflow that ensures that the proposed changes meet the minimal quality and functional guidelines of the Electron project.
type
String (optional) - One of the following:tasks
- Items in this category will be placed into the standard Tasks
category. There can be only one such category, and it will always be displayed at the bottom of the Jump List.frequent
- Displays a list of files frequently opened by the app, the name of the category and its items are set by Windows.recent
- Displays a list of files recently opened by the app, the name of the category and its items are set by Windows. Items may be added to this category indirectly using app.addRecentDocument(path)
.custom
- Displays tasks or file links, name
must be set by the app.name
String (optional) - Must be set if type
is custom
, otherwise it should be omitted.items
JumpListItem[] (optional) - Array of JumpListItem
objects if type
is tasks
or custom
, otherwise it should be omitted.Note: If a JumpListCategory
object has neither the type
nor the name
property set then its type
is assumed to be tasks
. If the name
property is set but the type
property is omitted then the type
is assumed to be custom
.
type
String (optional) - One of the following:task
- A task will launch an app with specific arguments.separator
- Can be used to separate items in the standard Tasks
category.file
- A file link will open a file using the app that created the Jump List, for this to work the app must be registered as a handler for the file type (though it doesn't have to be the default handler).path
String (optional) - Path of the file to open, should only be set if type
is file
.program
String (optional) - Path of the program to execute, usually you should specify process.execPath
which opens the current program. Should only be set if type
is task
.args
String (optional) - The command line arguments when program
is executed. Should only be set if type
is task
.title
String (optional) - The text to be displayed for the item in the Jump List. Should only be set if type
is task
.description
String (optional) - Description of the task (displayed in a tooltip). Should only be set if type
is task
.iconPath
String (optional) - The absolute path to an icon to be displayed in a Jump List, which can be an arbitrary resource file that contains an icon (e.g. .ico
, .exe
, .dll
). You can usually specify process.execPath
to show the program icon.iconIndex
Number (optional) - The index of the icon in the resource file. If a resource file contains multiple icons this value can be used to specify the zero-based index of the icon that should be displayed for this task. If a resource file contains only one icon, this property should be set to zero.workingDirectory
String (optional) - The working directory. Default is empty.ctrlKey
Boolean (optional) - whether the Control key was used in an accelerator to trigger the EventmetaKey
Boolean (optional) - whether a meta key was used in an accelerator to trigger the EventshiftKey
Boolean (optional) - whether a Shift key was used in an accelerator to trigger the EventaltKey
Boolean (optional) - whether an Alt key was used in an accelerator to trigger the EventtriggeredByAccelerator
Boolean (optional) - whether an accelerator was used to trigger the event as opposed to another user gesture like mouse clickInputEvent
type
String - The type of the event, can be keyDown
, keyUp
or char
.keyCode
String - The character that will be sent as the keyboard event. Should only use the valid key codes in Accelerator.This feature allows you to configure local and global keyboard shortcuts for your Electron application.
Local keyboard shortcuts are triggered only when the application is focused. To configure a local keyboard shortcut, you need to specify an accelerator
property when creating a MenuItem within the Menu module.
Starting with a working application from the Quick Start Guide, update the main.js
file with the following lines:
const { Menu, MenuItem } = require('electron') const menu = new Menu() menu.append(new MenuItem({ label: 'Electron', submenu: [{ role: 'help', accelerator: process.platform === 'darwin' ? 'Alt+Cmd+I' : 'Alt+Shift+I', click: () => { console.log('Electron rocks!') } }] })) Menu.setApplicationMenu(menu)
NOTE: In the code above, you can see that the accelerator differs based on the user's operating system. For MacOS, it is
Alt+Cmd+I
, whereas for Linux and Windows, it isAlt+Shift+I
.
After launching the Electron application, you should see the application menu along with the local shortcut you just defined:
If you click Help
or press the defined accelerator and then open the terminal that you ran your Electron application from, you will see the message that was generated after triggering the click
event: "Electron rocks!".
To configure a global keyboard shortcut, you need to use the globalShortcut module to detect keyboard events even when the application does not have keyboard focus.
Starting with a working application from the Quick Start Guide, update the main.js
file with the following lines:
const { app, globalShortcut } = require('electron') app.whenReady().then(() => { globalShortcut.register('Alt+CommandOrControl+I', () => { console.log('Electron loves global shortcuts!') }) }).then(createWindow)
NOTE: In the code above, the
CommandOrControl
combination usesCommand
on macOS andControl
on Windows/Linux.
After launching the Electron application, if you press the defined key combination then open the terminal that you ran your Electron application from, you will see that Electron loves global shortcuts!
If you want to handle keyboard shortcuts within a BrowserWindow, you can listen for the keyup
and keydown
DOM events inside the renderer process using the addEventListener() API.
window.addEventListener('keyup', doSomething, true)
Note the third parameter true
indicates that the listener will always receive key presses before other listeners so they can't have stopPropagation()
called on them.
The before-input-event
event is emitted before dispatching keydown
and keyup
events in the page. It can be used to catch and handle custom shortcuts that are not visible in the menu.
Starting with a working application from the Quick Start Guide, update the main.js
file with the following lines:
const { app, BrowserWindow } = require('electron') app.whenReady().then(() => { const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true } }) win.loadFile('index.html') win.webContents.on('before-input-event', (event, input) => { if (input.control && input.key.toLowerCase() === 'i') { console.log('Pressed Control+I') event.preventDefault() } }) })
After launching the Electron application, if you open the terminal that you ran your Electron application from and press Ctrl+I
key combination, you will see that this key combination was successfully intercepted.
If you don't want to do manual shortcut parsing, there are libraries that do advanced key detection, such as mousetrap. Below are examples of usage of the mousetrap
running in the Renderer process:
Mousetrap.bind('4', () => { console.log('4') }) Mousetrap.bind('?', () => { console.log('show shortcuts!') }) Mousetrap.bind('esc', () => { console.log('escape') }, 'keyup') // combinations Mousetrap.bind('command+shift+k', () => { console.log('command shift k') }) // map multiple combinations to the same callback Mousetrap.bind(['command+k', 'ctrl+k'], () => { console.log('command k or control k') // return false to prevent default behavior and stop event from bubbling return false }) // gmail style sequences Mousetrap.bind('g i', () => { console.log('go to inbox') }) Mousetrap.bind('* a', () => { console.log('select all') }) // konami code! Mousetrap.bind('up up down down left right left right b a enter', () => { console.log('konami code') })
On many Linux environments, you can add custom entries to the system launcher by modifying the .desktop
file. For Canonical's Unity documentation, see Adding Shortcuts to a Launcher. For details on a more generic implementation, see the freedesktop.org Specification.