algolia-indices/dist/tutorials.json

1189 строки
381 KiB
JSON
Исходник Постоянная ссылка Ответственный История

Этот файл содержит невидимые символы Юникода!

Этот файл содержит невидимые символы Юникода, которые могут быть отображены не так, как показано ниже. Если это намеренно, можете спокойно проигнорировать это предупреждение. Используйте кнопку Экранировать, чтобы показать скрытые символы.

Этот файл содержит неоднозначные символы Юникода, которые могут быть перепутаны с другими в текущей локали. Если это намеренно, можете спокойно проигнорировать это предупреждение. Используйте кнопку Экранировать, чтобы подсветить эти символы.

{
"name": "tutorials",
"records": [
{
"objectID": "tutorial-accessibility",
"title": "Accessibility",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/accessibility.md",
"url": "https://electronjs.org/docs/tutorial/accessibility",
"slug": "accessibility",
"body": "Accessibility\nMaking accessible applications is important and we're happy to provide\nfunctionality to Devtron and Spectron that gives\ndevelopers the opportunity to make their apps better for everyone.\n\nAccessibility concerns in Electron applications are similar to those of\nwebsites because they're both ultimately HTML. With Electron apps, however,\nyou can't use the online resources for accessibility audits because your app\ndoesn't have a URL to point the auditor to.\nThese features bring those auditing tools to your Electron app. You can\nchoose to add audits to your tests with Spectron or use them within DevTools\nwith Devtron. Read on for a summary of the tools.\n\nSpectron\nIn the testing framework Spectron, you can now audit each window and <webview>\ntag in your application. For example:\napp.client.auditAccessibility().then(function (audit) {\n if (audit.failed) {\n console.error(audit.message)\n }\n})\n\nYou can read more about this feature in Spectron's documentation.\n\nDevtron\nIn Devtron, there is an accessibility tab which will allow you to audit a\npage in your app, sort and filter the results.\n\nBoth of these tools are using the Accessibility Developer Tools\nlibrary built by Google for Chrome. You can learn more about the accessibility\naudit rules this library uses on that repository's wiki.\nIf you know of other great accessibility tools for Electron, add them to the\naccessibility documentation with a pull request.\n\nManually enabling accessibility features\nElectron applications will automatically enable accessibility features in the\npresence of assistive technology (e.g. JAWS\non Windows or VoiceOver on macOS).\nSee Chrome's accessibility documentation for more details.\nYou can also manually toggle these features either within your Electron application\nor by setting flags in third-party native software.\n\nUsing Electron's API\nBy using the app.setAccessibilitySupportEnabled(enabled)\nAPI, you can manually expose Chrome's accessibility tree to users in the application preferences.\nNote that the user's system assistive utilities have priority over this setting and\nwill override it.\n\nWithin third-party software\n\nmacOS\nOn macOS, third-party assistive technology can toggle accessibility features inside\nElectron applications by setting the AXManualAccessibility attribute\nprogrammatically:\nCFStringRef kAXManualAccessibility = CFSTR(\"AXManualAccessibility\");\n\n+ (void)enableAccessibility:(BOOL)enable inElectronApplication:(NSRunningApplication *)app\n{\n AXUIElementRef appRef = AXUIElementCreateApplication(app.processIdentifier);\n if (appRef == nil)\n return;\n\n CFBooleanRef value = enable ? kCFBooleanTrue : kCFBooleanFalse;\n AXUIElementSetAttributeValue(appRef, kAXManualAccessibility, value);\n CFRelease(appRef);\n}\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Accessibility",
"doc:accessibility",
"tutorial:Accessibility",
"tutorial:accessibility"
]
},
{
"objectID": "tutorial-application-debugging",
"title": "Application Debugging",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/application-debugging.md",
"url": "https://electronjs.org/docs/tutorial/application-debugging",
"slug": "application-debugging",
"body": "Application Debugging\nWhenever your Electron application is not behaving the way you wanted it to,\nan array of debugging tools might help you find coding errors, performance\nbottlenecks, or optimization opportunities.\n\nRenderer Process\nThe most comprehensive tool to debug individual renderer processes is the\nChromium Developer Toolset. It is available for all renderer processes,\nincluding instances of BrowserWindow, BrowserView, and WebView. You\ncan open them programmatically by calling the openDevTools() API on the\nwebContents of the instance:\nconst { BrowserWindow } = require('electron')\n\nconst win = new BrowserWindow()\nwin.webContents.openDevTools()\n\nGoogle offers excellent documentation for their developer tools.\nWe recommend that you make yourself familiar with them - they are usually one\nof the most powerful utilities in any Electron Developer's tool belt.\n\nMain Process\nDebugging the main process is a bit trickier, since you cannot open\ndeveloper tools for them. The Chromium Developer Tools can be used\nto debug Electron's main process thanks to a closer collaboration\nbetween Google / Chrome and Node.js, but you might encounter oddities like\nrequire not being present in the console.\nFor more information, see the Debugging the Main Process documentation.\n\nV8 Crashes\nIf the V8 context crashes, the DevTools will display this message.\nDevTools was disconnected from the page. Once page is reloaded, DevTools will automatically reconnect.\nChromium logs can be enabled via the ELECTRON_ENABLE_LOGGING environment variable. For more information, see the environment variables documentation.\nAlternatively, the command line argument --enable-logging can be passed. More information is available in the command line switches documentation.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Application Debugging",
"doc:application-debugging",
"tutorial:Application Debugging",
"tutorial:application-debugging"
]
},
{
"objectID": "tutorial-application-distribution",
"title": "Application Distribution",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/application-distribution.md",
"url": "https://electronjs.org/docs/tutorial/application-distribution",
"slug": "application-distribution",
"body": "Application Distribution\n\nOverview\nTo distribute your app with Electron, you need to package and rebrand it.\nTo do this, you can either use specialized tooling or manual approaches.\n\nWith tooling\nYou can use the following tools to distribute your application:\n\nelectron-forge\nelectron-builder\nelectron-packager\n\nThese tools will take care of all the steps you need to take to end up with a\ndistributable Electron application, such as bundling your application,\nrebranding the executable, and setting the right icons.\nYou can check the example of how to package your app with electron-forge in\nour Quick Start Guide.\n\nManual distribution\n\nWith prebuilt binaries\nTo distribute your app manually, you need to download Electron's prebuilt\nbinaries. Next, the folder\ncontaining your app should be named app and placed in Electron's resources\ndirectory as shown in the following examples.\n\nNOTE: the location of Electron's prebuilt binaries is indicated\nwith electron/ in the examples below.\n\nOn macOS:\nelectron/Electron.app/Contents/Resources/app/\n├── package.json\n├── main.js\n└── index.html\n\nOn Windows and Linux:\nelectron/resources/app\n├── package.json\n├── main.js\n└── index.html\n\nThen execute Electron.app on macOS, electron on Linux, or electron.exe\non Windows, and Electron will start as your app. The electron directory\nwill then be your distribution to deliver to users.\n\nWith an app source code archive\nInstead of from shipping your app by copying all of its source files, you can\npackage your app into an asar archive to improve the performance of reading\nfiles on platforms like Windows, if you are not already using a bundler such\nas Parcel or Webpack.\nTo use an asar archive to replace the app folder, you need to rename the\narchive to app.asar, and put it under Electron's resources directory like\nbelow, and Electron will then try to read the archive and start from it.\nOn macOS:\nelectron/Electron.app/Contents/Resources/\n└── app.asar\n\nOn Windows and Linux:\nelectron/resources/\n└── app.asar\n\nYou can find more details on how to use asar in the\nelectron/asar repository.\n\nRebranding with downloaded binaries\nAfter bundling your app into Electron, you will want to rebrand Electron\nbefore distributing it to users.\n\nmacOS\nYou can rename Electron.app to any name you want, and you also have to rename\nthe CFBundleDisplayName, CFBundleIdentifier and CFBundleName fields in the\nfollowing files:\n\nElectron.app/Contents/Info.plist\nElectron.app/Contents/Frameworks/Electron Helper.app/Contents/Info.plist\n\nYou can also rename the helper app to avoid showing Electron Helper in the\nActivity Monitor, but make sure you have renamed the helper app's executable\nfile's name.\nThe structure of a renamed app would be like:\nMyApp.app/Contents\n├── Info.plist\n├── MacOS/\n│   └── MyApp\n└── Frameworks/\n └── MyApp Helper.app\n ├── Info.plist\n └── MacOS/\n    └── MyApp Helper\n\n\nWindows\nYou can rename electron.exe to any name you like, and edit its icon and other\ninformation with tools like rcedit.\n\nLinux\nYou can rename the electron executable to any name you like.\n\nRebranding by rebuilding Electron from source\nIt is also possible to rebrand Electron by changing the product name and\nbuilding it from source. To do this you need to set the build argument\ncorresponding to the product name (electron_product_name = \"YourProductName\")\nin the args.gn file and rebuild.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Application Distribution",
"doc:application-distribution",
"tutorial:Application Distribution",
"tutorial:application-distribution"
]
},
{
"objectID": "tutorial-automated-testing-with-a-custom-driver",
"title": "Automated Testing with a Custom Driver",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/automated-testing-with-a-custom-driver.md",
"url": "https://electronjs.org/docs/tutorial/automated-testing-with-a-custom-driver",
"slug": "automated-testing-with-a-custom-driver",
"body": "Automated Testing with a Custom Driver\nTo 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.\nTo 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:\nconst childProcess = require('child_process')\nconst electronPath = require('electron')\n\n// spawn the process\nconst env = { /* ... */ }\nconst stdio = ['inherit', 'inherit', 'inherit', 'ipc']\nconst appProcess = childProcess.spawn(electronPath, ['./app'], { stdio, env })\n\n// listen for IPC messages from the app\nappProcess.on('message', (msg) => {\n // ...\n})\n\n// send an IPC message to the app\nappProcess.send({ my: 'message' })\n\nFrom within the Electron app, you can listen for messages and send replies using the Node.js process API:\n// listen for IPC messages from the test suite\nprocess.on('message', (msg) => {\n // ...\n})\n\n// send an IPC message to the test suite\nprocess.send({ my: 'message' })\n\nWe can now communicate from the test suite to the Electron app using the appProcess object.\nFor 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:\nclass TestDriver {\n constructor ({ path, args, env }) {\n this.rpcCalls = []\n\n // start child process\n env.APP_TEST_DRIVER = 1 // let the app know it should listen for messages\n this.process = childProcess.spawn(path, args, { stdio: ['inherit', 'inherit', 'inherit', 'ipc'], env })\n\n // handle rpc responses\n this.process.on('message', (message) => {\n // pop the handler\n const rpcCall = this.rpcCalls[message.msgId]\n if (!rpcCall) return\n this.rpcCalls[message.msgId] = null\n // reject/resolve\n if (message.reject) rpcCall.reject(message.reject)\n else rpcCall.resolve(message.resolve)\n })\n\n // wait for ready\n this.isReady = this.rpc('isReady').catch((err) => {\n console.error('Application failed to start', err)\n this.stop()\n process.exit(1)\n })\n }\n\n // simple RPC call\n // to use: driver.rpc('method', 1, 2, 3).then(...)\n async rpc (cmd, ...args) {\n // send rpc request\n const msgId = this.rpcCalls.length\n this.process.send({ msgId, cmd, args })\n return new Promise((resolve, reject) => this.rpcCalls.push({ resolve, reject }))\n }\n\n stop () {\n this.process.kill()\n }\n}\n\nIn the app, you'd need to write a simple handler for the RPC calls:\nif (process.env.APP_TEST_DRIVER) {\n process.on('message', onMessage)\n}\n\nasync function onMessage ({ msgId, cmd, args }) {\n let method = METHODS[cmd]\n if (!method) method = () => new Error('Invalid method: ' + cmd)\n try {\n const resolve = await method(...args)\n process.send({ msgId, resolve })\n } catch (err) {\n const reject = {\n message: err.message,\n stack: err.stack,\n name: err.name\n }\n process.send({ msgId, reject })\n }\n}\n\nconst METHODS = {\n isReady () {\n // do any setup needed\n return true\n }\n // define your RPC-able methods here\n}\n\nThen, in your test suite, you can use your test-driver as follows:\nconst test = require('ava')\nconst electronPath = require('electron')\n\nconst app = new TestDriver({\n path: electronPath,\n args: ['./app'],\n env: {\n NODE_ENV: 'test'\n }\n})\ntest.before(async t => {\n await app.isReady\n})\ntest.after.always('cleanup', async t => {\n await app.stop()\n})\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Automated Testing with a Custom Driver",
"doc:automated-testing-with-a-custom-driver",
"tutorial:Automated Testing with a Custom Driver",
"tutorial:automated-testing-with-a-custom-driver"
]
},
{
"objectID": "tutorial-azure-vm-setup",
"title": "Updating an Appveyor Azure Image",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/development/azure-vm-setup.md",
"url": "https://electronjs.org/docs/development/azure-vm-setup",
"slug": "azure-vm-setup",
"body": "Updating an Appveyor Azure Image\nElectron 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.\nOccasionally we need to update these images owing to changes in Chromium or other miscellaneous build requirement changes.\nExample Use Case:\n* We need `VS15.9` and we have `VS15.7` installed; this would require us to update an Azure image.\n\n\n\nIdentify the image you wish to modify.\n\nIn appveyor.yml, the image is identified by the property image.\nThe names used correspond to the \"images\" defined for a build cloud, eg the libcc-20 cloud.\n\nFind the image you wish to modify in the build cloud and make note of the VHD Blob Path for that image, which is the value for that corresponding key.\nYou will need this URI path to copy into a new image.\n\nYou will also need the storage account name which is labeled in AppVeyor as the Disk Storage Account Name\n\n\n\nGet the Azure storage account key\n\nLog into Azure using credentials stored in LastPass (under Azure Enterprise) and then find the storage account corresponding to the name found in AppVeyor.\nExample, for appveyorlibccbuilds Disk Storage Account Name you'd look for appveyorlibccbuilds in the list of storage accounts @ Home < Storage Accounts\nClick into it and look for Access Keys, and then you can use any of the keys present in the list.\n\n\n\n\n\nGet the full virtual machine image URI from Azure\n\nNavigate to Home < Storage Accounts < $ACCT_NAME < Blobs < Images\nIn the following list, look for the VHD path name you got from Appveyor and then click on it.\nCopy the whole URL from the top of the subsequent window.\n\n\n\n\n\nCopy the image using the Copy Master Image PowerShell script.\n\nIt is essential to copy the VM because if you spin up a VM against an image that image cannot at the same time be used by AppVeyor.\nUse the storage account name, key, and URI obtained from Azure to run this script.\nSee Step 3 for URI & when prompted, press enter to use same storage account as destination.\nUse default destination container name (images)\nAlso, when naming the copy, use a name that indicates what the new image will contain (if that has changed) and date stamp.\nEx. libcc-20core-vs2017-15.9-2019-04-15.vhd\n\n\nGo into Azure and get the URI for the newly created image as described in a previous step\n\n\n\nSpin up a new VM using the Create Master VM from VHD PowerShell.\n\nFrom PowerShell, execute ps1 file with ./create_master_vm_from_vhd.ps1\nYou will need the credential information available in the AppVeyor build cloud definition.\nThis includes:\nClient ID\nClient Secret\nTenant ID\nSubscription ID\nResource Group\nVirtual Network\n\n\nYou will also need to specify\nMaster VM name - just a unique name to identify the temporary VM\nMaster VM size - use Standard_F32s_v2\nMaster VHD URI - use URI obtained @ end of previous step\nLocation use East US\n\n\n\n\nLog back into Azure and find the VM you just created in Home < Virtual Machines < $YOUR_NEW_VM\n\nYou can download a RDP (Remote Desktop) file to access the VM.\n\n\n\nUsing Microsoft Remote Desktop, click Connect to connect to the VM.\n\nCredentials for logging into the VM are found in LastPass under the AppVeyor Enterprise master VM credentials.\n\n\n\nModify the VM as required.\n\n\nShut down the VM and then delete it in Azure.\n\n\nAdd the new image to the Appveyor Cloud settings or modify an existing image to point to the new VHD.\n\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Updating an Appveyor Azure Image",
"doc:azure-vm-setup",
"tutorial:Updating an Appveyor Azure Image",
"tutorial:azure-vm-setup"
]
},
{
"objectID": "tutorial-boilerplates-and-clis",
"title": "Boilerplates and CLIs",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/boilerplates-and-clis.md",
"url": "https://electronjs.org/docs/tutorial/boilerplates-and-clis",
"slug": "boilerplates-and-clis",
"body": "Boilerplates and CLIs\nElectron development is unopinionated - there is no \"one true way\" to develop,\nbuild, package, or release an Electron application. Additional features for\nElectron, both for build- and run-time, can usually be found on\nnpm in individual packages, allowing developers to build both\nthe app and build pipeline they need.\nThat level of modularity and extendability ensures that all developers working\nwith Electron, both big and small in team-size, are never restricted in what\nthey can or cannot do at any time during their development lifecycle. However,\nfor many developers, one of the community-driven boilerplates or command line\ntools might make it dramatically easier to compile, package, and release an\napp.\n\nBoilerplate vs CLI\nA boilerplate is only a starting point - a canvas, so to speak - from which\nyou build your application. They usually come in the form of a repository you\ncan clone and customize to your heart's content.\nA command line tool on the other hand continues to support you throughout the\ndevelopment and release. They are more helpful and supportive but enforce\nguidelines on how your code should be structured and built. Especially for\nbeginners, using a command line tool is likely to be helpful.\n\nelectron-forge\nA \"complete tool for building modern Electron applications\". Electron Forge\nunifies the existing (and well maintained) build tools for Electron development\ninto a cohesive package so that anyone can jump right in to Electron\ndevelopment.\nForge 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\ngreater Electron community (like electron-packager) –\nchanges made by Electron maintainers (like Slack) benefit Forge's users, too.\nYou can find more information and documentation on electronforge.io.\n\nelectron-builder\nA \"complete solution to package and build a ready-for-distribution Electron app\"\nthat focuses on an integrated experience. electron-builder adds one\nsingle dependency focused on simplicity and manages all further requirements\ninternally.\nelectron-builder replaces features and modules used by the Electron\nmaintainers (such as the auto-updater) with custom ones. They are generally\ntighter integrated but will have less in common with popular Electron apps\nlike Atom, Visual Studio Code, or Slack.\nYou can find more information and documentation in the repository.\n\nelectron-react-boilerplate\nIf you don't want any tools but only a solid boilerplate to build from,\nCT Lin's electron-react-boilerplate might be worth\na look. It's quite popular in the community and uses electron-builder\ninternally.\n\nOther Tools and Boilerplates\nThe \"Awesome Electron\" list contains more tools and boilerplates\nto choose from. If you find the length of the list intimidating, don't\nforget that adding tools as you go along is a valid approach, too.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Boilerplates and CLIs",
"doc:boilerplates-and-clis",
"tutorial:Boilerplates and CLIs",
"tutorial:boilerplates-and-clis"
]
},
{
"objectID": "tutorial-breaking-changes",
"title": "Breaking Changes",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/breaking-changes.md",
"url": "https://electronjs.org/docs/breaking-changes",
"slug": "breaking-changes",
"body": "Breaking Changes\nBreaking changes will be documented here, and deprecation warnings added to JS code where possible, at least one major version before the change is made.\n\nTypes of Breaking Changes\nThis document uses the following convention to categorize breaking changes:\n\nAPI Changed: An API was changed in such a way that code that has not been updated is guaranteed to throw an exception.\nBehavior Changed: The behavior of Electron has changed, but not in such a way that an exception will necessarily be thrown.\nDefault Changed: Code depending on the old default may break, not necessarily throwing an exception. The old behavior can be restored by explicitly specifying the value.\nDeprecated: An API was marked as deprecated. The API will continue to function, but will emit a deprecation warning, and will be removed in a future release.\nRemoved: An API or feature was removed, and is no longer supported by Electron.\n\n\nPlanned Breaking API Changes (14.0)\n\nAPI Changed: window.(open)\nThe optional parameter frameName will no longer set the title of the window. This now follows the specification described by the native documentation under the corresponding parameter windowName.\nIf you were using this parameter to set the title of a window, you can instead use win.setTitle(title).\n\nRemoved: worldSafeExecuteJavaScript\nIn Electron 14, worldSafeExecuteJavaScript will be removed. There is no alternative, please\nensure your code works with this property enabled. It has been enabled by default since Electron\n12.\nYou will be affected by this change if you use either webFrame.executeJavaScript or webFrame.executeJavaScriptInIsolatedWorld. You will need to ensure that values returned by either of those methods are supported by the Context Bridge API as these methods use the same value passing semantics.\n\nPlanned Breaking API Changes (13.0)\n\nAPI Changed: session.setPermissionCheckHandler(handler)\nThe handler methods first parameter was previously always a webContents, it can now sometimes be null. You should use the requestingOrigin, embeddingOrigin and securityOrigin properties to respond to the permission check correctly. As the webContents can be null it can no longer be relied on.\n// Old code\nsession.setPermissionCheckHandler((webContents, permission) => {\n if (webContents.getURL().startsWith('https://google.com/') && permission === 'notification') {\n return true\n }\n return false\n})\n\n// Replace with\nsession.setPermissionCheckHandler((webContents, permission, requestingOrigin) => {\n if (new URL(requestingOrigin).hostname === 'google.com' && permission === 'notification') {\n return true\n }\n return false\n})\n\n\nRemoved: shell.moveItemToTrash()\nThe deprecated synchronous shell.moveItemToTrash() API has been removed. Use\nthe asynchronous shell.trashItem() instead.\n// Removed in Electron 13\nshell.moveItemToTrash(path)\n// Replace with\nshell.trashItem(path).then(/* ... */)\n\n\nRemoved: BrowserWindow extension APIs\nThe deprecated extension APIs have been removed:\n\nBrowserWindow.addExtension(path)\nBrowserWindow.addDevToolsExtension(path)\nBrowserWindow.removeExtension(name)\nBrowserWindow.removeDevToolsExtension(name)\nBrowserWindow.getExtensions()\nBrowserWindow.getDevToolsExtensions()\n\nUse the session APIs instead:\n\nses.loadExtension(path)\nses.removeExtension(extension_id)\nses.getAllExtensions()\n\n// Removed in Electron 13\nBrowserWindow.addExtension(path)\nBrowserWindow.addDevToolsExtension(path)\n// Replace with\nsession.defaultSession.loadExtension(path)\n\n// Removed in Electron 13\nBrowserWindow.removeExtension(name)\nBrowserWindow.removeDevToolsExtension(name)\n// Replace with\nsession.defaultSession.removeExtension(extension_id)\n\n// Removed in Electron 13\nBrowserWindow.getExtensions()\nBrowserWindow.getDevToolsExtensions()\n// Replace with\nsession.defaultSession.getAllExtensions()\n\n\nRemoved: methods in systemPreferences\nThe following systemPreferences methods have been deprecated:\n\nsystemPreferences.isDarkMode()\nsystemPreferences.isInvertedColorScheme()\nsystemPreferences.isHighContrastColorScheme()\n\nUse the following nativeTheme properties instead:\n\nnativeTheme.shouldUseDarkColors\nnativeTheme.shouldUseInvertedColorScheme\nnativeTheme.shouldUseHighContrastColors\n\n// Removed in Electron 13\nsystemPreferences.isDarkMode()\n// Replace with\nnativeTheme.shouldUseDarkColors\n\n// Removed in Electron 13\nsystemPreferences.isInvertedColorScheme()\n// Replace with\nnativeTheme.shouldUseInvertedColorScheme\n\n// Removed in Electron 13\nsystemPreferences.isHighContrastColorScheme()\n// Replace with\nnativeTheme.shouldUseHighContrastColors\n\n\nPlanned Breaking API Changes (12.0)\n\nRemoved: Pepper Flash support\nChromium has removed support for Flash, and so we must follow suit. See\nChromium's Flash Roadmap for more\ndetails.\n\nDefault Changed: worldSafeExecuteJavaScript defaults to true\nIn Electron 12, worldSafeExecuteJavaScript will be enabled by default. To restore\nthe previous behavior, worldSafeExecuteJavaScript: false must be specified in WebPreferences.\nPlease note that setting this option to false is insecure.\nThis option will be removed in Electron 14 so please migrate your code to support the default\nvalue.\n\nDefault Changed: contextIsolation defaults to true\nIn Electron 12, contextIsolation will be enabled by default. To restore\nthe previous behavior, contextIsolation: false must be specified in WebPreferences.\nWe recommend having contextIsolation enabled for the security of your application.\nAnother implication is that require() cannot be used in the renderer process unless\nnodeIntegration is true and contextIsolation is false.\nFor more details see: https://github.com/electron/electron/issues/23506\n\nRemoved: crashReporter.getCrashesDirectory()\nThe crashReporter.getCrashesDirectory method has been removed. Usage\nshould be replaced by app.getPath('crashDumps').\n// Removed in Electron 12\ncrashReporter.getCrashesDirectory()\n// Replace with\napp.getPath('crashDumps')\n\n\nRemoved: crashReporter methods in the renderer process\nThe following crashReporter methods are no longer available in the renderer\nprocess:\n\ncrashReporter.start\ncrashReporter.getLastCrashReport\ncrashReporter.getUploadedReports\ncrashReporter.getUploadToServer\ncrashReporter.setUploadToServer\ncrashReporter.getCrashesDirectory\n\nThey should be called only from the main process.\nSee #23265 for more details.\n\nDefault Changed: crashReporter.start({ compress: true })\nThe default value of the compress option to crashReporter.start has changed\nfrom false to true. This means that crash dumps will be uploaded to the\ncrash ingestion server with the Content-Encoding: gzip header, and the body\nwill be compressed.\nIf your crash ingestion server does not support compressed payloads, you can\nturn off compression by specifying { compress: false } in the crash reporter\noptions.\n\nDeprecated: remote module\nThe remote module is deprecated in Electron 12, and will be removed in\nElectron 14. It is replaced by the\n@electron/remote module.\n// Deprecated in Electron 12:\nconst { BrowserWindow } = require('electron').remote\n\n// Replace with:\nconst { BrowserWindow } = require('@electron/remote')\n\n// In the main process:\nrequire('@electron/remote/main').initialize()\n\n\nDeprecated: shell.moveItemToTrash()\nThe synchronous shell.moveItemToTrash() has been replaced by the new,\nasynchronous shell.trashItem().\n// Deprecated in Electron 12\nshell.moveItemToTrash(path)\n// Replace with\nshell.trashItem(path).then(/* ... */)\n\n\nPlanned Breaking API Changes (11.0)\n\nRemoved: BrowserView.{destroy, fromId, fromWebContents, getAllViews} and id property of BrowserView\nThe experimental APIs BrowserView.{destroy, fromId, fromWebContents, getAllViews}\nhave now been removed. Additionally, the id property of BrowserView\nhas also been removed.\nFor more detailed information, see #23578.\n\nPlanned Breaking API Changes (10.0)\n\nDeprecated: companyName argument to crashReporter.start()\nThe companyName argument to crashReporter.start(), which was previously\nrequired, is now optional, and further, is deprecated. To get the same\nbehavior in a non-deprecated way, you can pass a companyName value in\nglobalExtra.\n// Deprecated in Electron 10\ncrashReporter.start({ companyName: 'Umbrella Corporation' })\n// Replace with\ncrashReporter.start({ globalExtra: { _companyName: 'Umbrella Corporation' } })\n\n\nDeprecated: crashReporter.getCrashesDirectory()\nThe crashReporter.getCrashesDirectory method has been deprecated. Usage\nshould be replaced by app.getPath('crashDumps').\n// Deprecated in Electron 10\ncrashReporter.getCrashesDirectory()\n// Replace with\napp.getPath('crashDumps')\n\n\nDeprecated: crashReporter methods in the renderer process\nCalling the following crashReporter methods from the renderer process is\ndeprecated:\n\ncrashReporter.start\ncrashReporter.getLastCrashReport\ncrashReporter.getUploadedReports\ncrashReporter.getUploadToServer\ncrashReporter.setUploadToServer\ncrashReporter.getCrashesDirectory\n\nThe only non-deprecated methods remaining in the crashReporter module in the\nrenderer are addExtraParameter, removeExtraParameter and getParameters.\nAll above methods remain non-deprecated when called from the main process.\nSee #23265 for more details.\n\nDeprecated: crashReporter.start({ compress: false })\nSetting { compress: false } in crashReporter.start is deprecated. Nearly\nall crash ingestion servers support gzip compression. This option will be\nremoved in a future version of Electron.\n\nRemoved: Browser Window Affinity\nThe affinity option when constructing a new BrowserWindow will be removed\nas part of our plan to more closely align with Chromium's process model for security,\nperformance and maintainability.\nFor more detailed information see #18397.\n\nDefault Changed: enableRemoteModule defaults to false\nIn Electron 9, using the remote module without explicitly enabling it via the\nenableRemoteModule WebPreferences option began emitting a warning. In\nElectron 10, the remote module is now disabled by default. To use the remote\nmodule, enableRemoteModule: true must be specified in WebPreferences:\nconst w = new BrowserWindow({\n webPreferences: {\n enableRemoteModule: true\n }\n})\n\nWe recommend moving away from the remote\nmodule.\n\nprotocol.unregisterProtocol\n\nprotocol.uninterceptProtocol\nThe APIs are now synchronous and the optional callback is no longer needed.\n// Deprecated\nprotocol.unregisterProtocol(scheme, () => { /* ... */ })\n// Replace with\nprotocol.unregisterProtocol(scheme)\n\n\nprotocol.registerFileProtocol\n\nprotocol.registerBufferProtocol\n\nprotocol.registerStringProtocol\n\nprotocol.registerHttpProtocol\n\nprotocol.registerStreamProtocol\n\nprotocol.interceptFileProtocol\n\nprotocol.interceptStringProtocol\n\nprotocol.interceptBufferProtocol\n\nprotocol.interceptHttpProtocol\n\nprotocol.interceptStreamProtocol\nThe APIs are now synchronous and the optional callback is no longer needed.\n// Deprecated\nprotocol.registerFileProtocol(scheme, handler, () => { /* ... */ })\n// Replace with\nprotocol.registerFileProtocol(scheme, handler)\n\nThe registered or intercepted protocol does not have effect on current page\nuntil navigation happens.\n\nprotocol.isProtocolHandled\nThis API is deprecated and users should use protocol.isProtocolRegistered\nand protocol.isProtocolIntercepted instead.\n// Deprecated\nprotocol.isProtocolHandled(scheme).then(() => { /* ... */ })\n// Replace with\nconst isRegistered = protocol.isProtocolRegistered(scheme)\nconst isIntercepted = protocol.isProtocolIntercepted(scheme)\n\n\nPlanned Breaking API Changes (9.0)\n\nDefault Changed: Loading non-context-aware native modules in the renderer process is disabled by default\nAs of Electron 9 we do not allow loading of non-context-aware native modules in\nthe renderer process. This is to improve security, performance and maintainability\nof Electron as a project.\nIf this impacts you, you can temporarily set app.allowRendererProcessReuse to false\nto revert to the old behavior. This flag will only be an option until Electron 11 so\nyou should plan to update your native modules to be context aware.\nFor more detailed information see #18397.\n\nDeprecated: BrowserWindow extension APIs\nThe following extension APIs have been deprecated:\n\nBrowserWindow.addExtension(path)\nBrowserWindow.addDevToolsExtension(path)\nBrowserWindow.removeExtension(name)\nBrowserWindow.removeDevToolsExtension(name)\nBrowserWindow.getExtensions()\nBrowserWindow.getDevToolsExtensions()\n\nUse the session APIs instead:\n\nses.loadExtension(path)\nses.removeExtension(extension_id)\nses.getAllExtensions()\n\n// Deprecated in Electron 9\nBrowserWindow.addExtension(path)\nBrowserWindow.addDevToolsExtension(path)\n// Replace with\nsession.defaultSession.loadExtension(path)\n\n// Deprecated in Electron 9\nBrowserWindow.removeExtension(name)\nBrowserWindow.removeDevToolsExtension(name)\n// Replace with\nsession.defaultSession.removeExtension(extension_id)\n\n// Deprecated in Electron 9\nBrowserWindow.getExtensions()\nBrowserWindow.getDevToolsExtensions()\n// Replace with\nsession.defaultSession.getAllExtensions()\n\n\nRemoved: <webview>.getWebContents()\nThis API, which was deprecated in Electron 8.0, is now removed.\n// Removed in Electron 9.0\nwebview.getWebContents()\n// Replace with\nconst { remote } = require('electron')\nremote.webContents.fromId(webview.getWebContentsId())\n\n\nRemoved: webFrame.setLayoutZoomLevelLimits()\nChromium has removed support for changing the layout zoom level limits, and it\nis beyond Electron's capacity to maintain it. The function was deprecated in\nElectron 8.x, and has been removed in Electron 9.x. The layout zoom level limits\nare now fixed at a minimum of 0.25 and a maximum of 5.0, as defined\nhere.\n\nBehavior Changed: Sending non-JS objects over IPC now throws an exception\nIn Electron 8.0, IPC was changed to use the Structured Clone Algorithm,\nbringing significant performance improvements. To help ease the transition, the\nold IPC serialization algorithm was kept and used for some objects that aren't\nserializable with Structured Clone. In particular, DOM objects (e.g. Element,\nLocation and DOMMatrix), Node.js objects backed by C++ classes (e.g.\nprocess.env, some members of Stream), and Electron objects backed by C++\nclasses (e.g. WebContents, BrowserWindow and WebFrame) are not\nserializable with Structured Clone. Whenever the old algorithm was invoked, a\ndeprecation warning was printed.\nIn Electron 9.0, the old serialization algorithm has been removed, and sending\nsuch non-serializable objects will now throw an \"object could not be cloned\"\nerror.\n\nAPI Changed: shell.openItem is now shell.openPath\nThe shell.openItem API has been replaced with an asynchronous shell.openPath API.\nYou can see the original API proposal and reasoning here.\n\nPlanned Breaking API Changes (8.0)\n\nBehavior Changed: Values sent over IPC are now serialized with Structured Clone Algorithm\nThe algorithm used to serialize objects sent over IPC (through\nipcRenderer.send, ipcRenderer.sendSync, WebContents.send and related\nmethods) has been switched from a custom algorithm to V8's built-in Structured\nClone Algorithm, the same algorithm used to serialize messages for\npostMessage. This brings about a 2x performance improvement for large\nmessages, but also brings some breaking changes in behavior.\n\nSending Functions, Promises, WeakMaps, WeakSets, or objects containing any\nsuch values, over IPC will now throw an exception, instead of silently\nconverting the functions to undefined.\n\n// Previously:\nipcRenderer.send('channel', { value: 3, someFunction: () => {} })\n// => results in { value: 3 } arriving in the main process\n\n// From Electron 8:\nipcRenderer.send('channel', { value: 3, someFunction: () => {} })\n// => throws Error(\"() => {} could not be cloned.\")\n\n\nNaN, Infinity and -Infinity will now be correctly serialized, instead\nof being converted to null.\nObjects containing cyclic references will now be correctly serialized,\ninstead of being converted to null.\nSet, Map, Error and RegExp values will be correctly serialized,\ninstead of being converted to {}.\nBigInt values will be correctly serialized, instead of being converted to\nnull.\nSparse arrays will be serialized as such, instead of being converted to dense\narrays with nulls.\nDate objects will be transferred as Date objects, instead of being\nconverted to their ISO string representation.\nTyped Arrays (such as Uint8Array, Uint16Array, Uint32Array and so on)\nwill be transferred as such, instead of being converted to Node.js Buffer.\nNode.js Buffer objects will be transferred as Uint8Arrays. You can\nconvert a Uint8Array back to a Node.js Buffer by wrapping the underlying\nArrayBuffer:\n\nBuffer.from(value.buffer, value.byteOffset, value.byteLength)\n\nSending any objects that aren't native JS types, such as DOM objects (e.g.\nElement, Location, DOMMatrix), Node.js objects (e.g. process.env,\nStream), or Electron objects (e.g. WebContents, BrowserWindow,\nWebFrame) is deprecated. In Electron 8, these objects will be serialized as\nbefore with a DeprecationWarning message, but starting in Electron 9, sending\nthese kinds of objects will throw a 'could not be cloned' error.\n\nDeprecated: <webview>.getWebContents()\nThis API is implemented using the remote module, which has both performance\nand security implications. Therefore its usage should be explicit.\n// Deprecated\nwebview.getWebContents()\n// Replace with\nconst { remote } = require('electron')\nremote.webContents.fromId(webview.getWebContentsId())\n\nHowever, it is recommended to avoid using the remote module altogether.\n// main\nconst { ipcMain, webContents } = require('electron')\n\nconst getGuestForWebContents = (webContentsId, contents) => {\n const guest = webContents.fromId(webContentsId)\n if (!guest) {\n throw new Error(`Invalid webContentsId: ${webContentsId}`)\n }\n if (guest.hostWebContents !== contents) {\n throw new Error('Access denied to webContents')\n }\n return guest\n}\n\nipcMain.handle('openDevTools', (event, webContentsId) => {\n const guest = getGuestForWebContents(webContentsId, event.sender)\n guest.openDevTools()\n})\n\n// renderer\nconst { ipcRenderer } = require('electron')\n\nipcRenderer.invoke('openDevTools', webview.getWebContentsId())\n\n\nDeprecated: webFrame.setLayoutZoomLevelLimits()\nChromium has removed support for changing the layout zoom level limits, and it\nis beyond Electron's capacity to maintain it. The function will emit a warning\nin Electron 8.x, and cease to exist in Electron 9.x. The layout zoom level\nlimits are now fixed at a minimum of 0.25 and a maximum of 5.0, as defined\nhere.\n\nDeprecated events in systemPreferences\nThe following systemPreferences events have been deprecated:\n\ninverted-color-scheme-changed\nhigh-contrast-color-scheme-changed\n\nUse the new updated event on the nativeTheme module instead.\n// Deprecated\nsystemPreferences.on('inverted-color-scheme-changed', () => { /* ... */ })\nsystemPreferences.on('high-contrast-color-scheme-changed', () => { /* ... */ })\n\n// Replace with\nnativeTheme.on('updated', () => { /* ... */ })\n\n\nDeprecated: methods in systemPreferences\nThe following systemPreferences methods have been deprecated:\n\nsystemPreferences.isDarkMode()\nsystemPreferences.isInvertedColorScheme()\nsystemPreferences.isHighContrastColorScheme()\n\nUse the following nativeTheme properties instead:\n\nnativeTheme.shouldUseDarkColors\nnativeTheme.shouldUseInvertedColorScheme\nnativeTheme.shouldUseHighContrastColors\n\n// Deprecated\nsystemPreferences.isDarkMode()\n// Replace with\nnativeTheme.shouldUseDarkColors\n\n// Deprecated\nsystemPreferences.isInvertedColorScheme()\n// Replace with\nnativeTheme.shouldUseInvertedColorScheme\n\n// Deprecated\nsystemPreferences.isHighContrastColorScheme()\n// Replace with\nnativeTheme.shouldUseHighContrastColors\n\n\nPlanned Breaking API Changes (7.0)\n\nDeprecated: Atom.io Node Headers URL\nThis is the URL specified as disturl in a .npmrc file or as the --dist-url\ncommand line flag when building native Node modules. Both will be supported for\nthe foreseeable future but it is recommended that you switch.\nDeprecated: https://atom.io/download/electron\nReplace with: https://electronjs.org/headers\n\nAPI Changed: session.clearAuthCache() no longer accepts options\nThe session.clearAuthCache API no longer accepts options for what to clear, and instead unconditionally clears the whole cache.\n// Deprecated\nsession.clearAuthCache({ type: 'password' })\n// Replace with\nsession.clearAuthCache()\n\n\nAPI Changed: powerMonitor.querySystemIdleState is now powerMonitor.getSystemIdleState\n// Removed in Electron 7.0\npowerMonitor.querySystemIdleState(threshold, callback)\n// Replace with synchronous API\nconst idleState = powerMonitor.getSystemIdleState(threshold)\n\n\nAPI Changed: powerMonitor.querySystemIdleTime is now powerMonitor.getSystemIdleTime\n// Removed in Electron 7.0\npowerMonitor.querySystemIdleTime(callback)\n// Replace with synchronous API\nconst idleTime = powerMonitor.getSystemIdleTime()\n\n\nAPI Changed: webFrame.setIsolatedWorldInfo replaces separate methods\n// Removed in Electron 7.0\nwebFrame.setIsolatedWorldContentSecurityPolicy(worldId, csp)\nwebFrame.setIsolatedWorldHumanReadableName(worldId, name)\nwebFrame.setIsolatedWorldSecurityOrigin(worldId, securityOrigin)\n// Replace with\nwebFrame.setIsolatedWorldInfo(\n worldId,\n {\n securityOrigin: 'some_origin',\n name: 'human_readable_name',\n csp: 'content_security_policy'\n })\n\n\nRemoved: marked property on getBlinkMemoryInfo\nThis property was removed in Chromium 77, and as such is no longer available.\n\nBehavior Changed: webkitdirectory attribute for <input type=\"file\"/> now lists directory contents\nThe webkitdirectory property on HTML file inputs allows them to select folders.\nPrevious versions of Electron had an incorrect implementation where the event.target.files\nof the input returned a FileList that returned one File corresponding to the selected folder.\nAs of Electron 7, that FileList is now list of all files contained within\nthe folder, similarly to Chrome, Firefox, and Edge\n(link to MDN docs).\nAs an illustration, take a folder with this structure:\nfolder\n├── file1\n├── file2\n└── file3\n\nIn Electron <=6, this would return a FileList with a File object for:\npath/to/folder\n\nIn Electron 7, this now returns a FileList with a File object for:\n/path/to/folder/file3\n/path/to/folder/file2\n/path/to/folder/file1\n\nNote that webkitdirectory no longer exposes the path to the selected folder.\nIf you require the path to the selected folder rather than the folder contents,\nsee the dialog.showOpenDialog API (link).\n\nAPI Changed: Callback-based versions of promisified APIs\nElectron 5 and Electron 6 introduced Promise-based versions of existing\nasynchronous APIs and deprecated their older, callback-based counterparts.\nIn Electron 7, all deprecated callback-based APIs are now removed.\nThese functions now only return Promises:\n\napp.getFileIcon() #15742\napp.dock.show() #16904\ncontentTracing.getCategories() #16583\ncontentTracing.getTraceBufferUsage() #16600\ncontentTracing.startRecording() #16584\ncontentTracing.stopRecording() #16584\ncontents.executeJavaScript() #17312\ncookies.flushStore() #16464\ncookies.get() #16464\ncookies.remove() #16464\ncookies.set() #16464\ndebugger.sendCommand() #16861\ndialog.showCertificateTrustDialog() #17181\ninAppPurchase.getProducts() #17355\ninAppPurchase.purchaseProduct()#17355\nnetLog.stopLogging() #16862\nsession.clearAuthCache() #17259\nsession.clearCache() #17185\nsession.clearHostResolverCache() #17229\nsession.clearStorageData() #17249\nsession.getBlobData() #17303\nsession.getCacheSize() #17185\nsession.resolveProxy() #17222\nsession.setProxy() #17222\nshell.openExternal() #16176\nwebContents.loadFile() #15855\nwebContents.loadURL() #15855\nwebContents.hasServiceWorker() #16535\nwebContents.printToPDF() #16795\nwebContents.savePage() #16742\nwebFrame.executeJavaScript() #17312\nwebFrame.executeJavaScriptInIsolatedWorld() #17312\nwebviewTag.executeJavaScript() #17312\nwin.capturePage() #15743\n\nThese functions now have two forms, synchronous and Promise-based asynchronous:\n\ndialog.showMessageBox()/dialog.showMessageBoxSync() #17298\ndialog.showOpenDialog()/dialog.showOpenDialogSync() #16973\ndialog.showSaveDialog()/dialog.showSaveDialogSync() #17054\n\n\nPlanned Breaking API Changes (6.0)\n\nAPI Changed: win.setMenu(null) is now win.removeMenu()\n// Deprecated\nwin.setMenu(null)\n// Replace with\nwin.removeMenu()\n\n\nAPI Changed: electron.screen in the renderer process should be accessed via remote\n// Deprecated\nrequire('electron').screen\n// Replace with\nrequire('electron').remote.screen\n\n\nAPI Changed: require()ing node builtins in sandboxed renderers no longer implicitly loads the remote version\n// Deprecated\nrequire('child_process')\n// Replace with\nrequire('electron').remote.require('child_process')\n\n// Deprecated\nrequire('fs')\n// Replace with\nrequire('electron').remote.require('fs')\n\n// Deprecated\nrequire('os')\n// Replace with\nrequire('electron').remote.require('os')\n\n// Deprecated\nrequire('path')\n// Replace with\nrequire('electron').remote.require('path')\n\n\nDeprecated: powerMonitor.querySystemIdleState replaced with powerMonitor.getSystemIdleState\n// Deprecated\npowerMonitor.querySystemIdleState(threshold, callback)\n// Replace with synchronous API\nconst idleState = powerMonitor.getSystemIdleState(threshold)\n\n\nDeprecated: powerMonitor.querySystemIdleTime replaced with powerMonitor.getSystemIdleTime\n// Deprecated\npowerMonitor.querySystemIdleTime(callback)\n// Replace with synchronous API\nconst idleTime = powerMonitor.getSystemIdleTime()\n\n\nDeprecated: app.enableMixedSandbox() is no longer needed\n// Deprecated\napp.enableMixedSandbox()\n\nMixed-sandbox mode is now enabled by default.\n\nDeprecated: Tray.setHighlightMode\nUnder macOS Catalina our former Tray implementation breaks.\nApple's native substitute doesn't support changing the highlighting behavior.\n// Deprecated\ntray.setHighlightMode(mode)\n// API will be removed in v7.0 without replacement.\n\n\nPlanned Breaking API Changes (5.0)\n\nDefault Changed: nodeIntegration and webviewTag default to false, contextIsolation defaults to true\nThe following webPreferences option default values are deprecated in favor of the new defaults listed below.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nPropertyDeprecated DefaultNew DefaultcontextIsolationfalsetruenodeIntegrationtruefalsewebviewTagnodeIntegration if set else truefalse\nE.g. Re-enabling the webviewTag\nconst w = new BrowserWindow({\n webPreferences: {\n webviewTag: true\n }\n})\n\n\nBehavior Changed: nodeIntegration in child windows opened via nativeWindowOpen\nChild windows opened with the nativeWindowOpen option will always have Node.js integration disabled, unless nodeIntegrationInSubFrames is true.\n\nAPI Changed: Registering privileged schemes must now be done before app ready\nRenderer process APIs webFrame.registerURLSchemeAsPrivileged and webFrame.registerURLSchemeAsBypassingCSP as well as browser process API protocol.registerStandardSchemes have been removed.\nA 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.\n\nDeprecated: webFrame.setIsolatedWorld* replaced with webFrame.setIsolatedWorldInfo\n// Deprecated\nwebFrame.setIsolatedWorldContentSecurityPolicy(worldId, csp)\nwebFrame.setIsolatedWorldHumanReadableName(worldId, name)\nwebFrame.setIsolatedWorldSecurityOrigin(worldId, securityOrigin)\n// Replace with\nwebFrame.setIsolatedWorldInfo(\n worldId,\n {\n securityOrigin: 'some_origin',\n name: 'human_readable_name',\n csp: 'content_security_policy'\n })\n\n\nAPI Changed: webFrame.setSpellCheckProvider now takes an asynchronous callback\nThe spellCheck callback is now asynchronous, and autoCorrectWord parameter has been removed.\n// Deprecated\nwebFrame.setSpellCheckProvider('en-US', true, {\n spellCheck: (text) => {\n return !spellchecker.isMisspelled(text)\n }\n})\n// Replace with\nwebFrame.setSpellCheckProvider('en-US', {\n spellCheck: (words, callback) => {\n callback(words.filter(text => spellchecker.isMisspelled(text)))\n }\n})\n\n\nAPI Changed: webContents.getZoomLevel and webContents.getZoomFactor are now synchronous\nwebContents.getZoomLevel and webContents.getZoomFactor no longer take callback parameters,\ninstead directly returning their number values.\n// Deprecated\nwebContents.getZoomLevel((level) => {\n console.log(level)\n})\n// Replace with\nconst level = webContents.getZoomLevel()\nconsole.log(level)\n\n// Deprecated\nwebContents.getZoomFactor((factor) => {\n console.log(factor)\n})\n// Replace with\nconst factor = webContents.getZoomFactor()\nconsole.log(factor)\n\n\nPlanned Breaking API Changes (4.0)\nThe following list includes the breaking API changes made in Electron 4.0.\n\napp.makeSingleInstance\n// Deprecated\napp.makeSingleInstance((argv, cwd) => {\n /* ... */\n})\n// Replace with\napp.requestSingleInstanceLock()\napp.on('second-instance', (event, argv, cwd) => {\n /* ... */\n})\n\n\napp.releaseSingleInstance\n// Deprecated\napp.releaseSingleInstance()\n// Replace with\napp.releaseSingleInstanceLock()\n\n\napp.getGPUInfo\napp.getGPUInfo('complete')\n// Now behaves the same with `basic` on macOS\napp.getGPUInfo('basic')\n\n\nwin_delay_load_hook\nWhen building native modules for windows, the win_delay_load_hook variable in\nthe module's binding.gyp must be true (which is the default). If this hook is\nnot present, then the native module will fail to load on Windows, with an error\nmessage like Cannot find module. See the native module\nguide for more.\n\nBreaking API Changes (3.0)\nThe following list includes the breaking API changes in Electron 3.0.\n\napp\n// Deprecated\napp.getAppMemoryInfo()\n// Replace with\napp.getAppMetrics()\n\n// Deprecated\nconst metrics = app.getAppMetrics()\nconst { memory } = metrics[0] // Deprecated property\n\n\nBrowserWindow\n// Deprecated\nconst optionsA = { webPreferences: { blinkFeatures: '' } }\nconst windowA = new BrowserWindow(optionsA)\n// Replace with\nconst optionsB = { webPreferences: { enableBlinkFeatures: '' } }\nconst windowB = new BrowserWindow(optionsB)\n\n// Deprecated\nwindow.on('app-command', (e, cmd) => {\n if (cmd === 'media-play_pause') {\n // do something\n }\n})\n// Replace with\nwindow.on('app-command', (e, cmd) => {\n if (cmd === 'media-play-pause') {\n // do something\n }\n})\n\n\nclipboard\n// Deprecated\nclipboard.readRtf()\n// Replace with\nclipboard.readRTF()\n\n// Deprecated\nclipboard.writeRtf()\n// Replace with\nclipboard.writeRTF()\n\n// Deprecated\nclipboard.readHtml()\n// Replace with\nclipboard.readHTML()\n\n// Deprecated\nclipboard.writeHtml()\n// Replace with\nclipboard.writeHTML()\n\n\ncrashReporter\n// Deprecated\ncrashReporter.start({\n companyName: 'Crashly',\n submitURL: 'https://crash.server.com',\n autoSubmit: true\n})\n// Replace with\ncrashReporter.start({\n companyName: 'Crashly',\n submitURL: 'https://crash.server.com',\n uploadToServer: true\n})\n\n\nnativeImage\n// Deprecated\nnativeImage.createFromBuffer(buffer, 1.0)\n// Replace with\nnativeImage.createFromBuffer(buffer, {\n scaleFactor: 1.0\n})\n\n\nprocess\n// Deprecated\nconst info = process.getProcessMemoryInfo()\n\n\nscreen\n// Deprecated\nscreen.getMenuBarHeight()\n// Replace with\nscreen.getPrimaryDisplay().workArea\n\n\nsession\n// Deprecated\nses.setCertificateVerifyProc((hostname, certificate, callback) => {\n callback(true)\n})\n// Replace with\nses.setCertificateVerifyProc((request, callback) => {\n callback(0)\n})\n\n\nTray\n// Deprecated\ntray.setHighlightMode(true)\n// Replace with\ntray.setHighlightMode('on')\n\n// Deprecated\ntray.setHighlightMode(false)\n// Replace with\ntray.setHighlightMode('off')\n\n\nwebContents\n// Deprecated\nwebContents.openDevTools({ detach: true })\n// Replace with\nwebContents.openDevTools({ mode: 'detach' })\n\n// Removed\nwebContents.setSize(options)\n// There is no replacement for this API\n\n\nwebFrame\n// Deprecated\nwebFrame.registerURLSchemeAsSecure('app')\n// Replace with\nprotocol.registerStandardSchemes(['app'], { secure: true })\n\n// Deprecated\nwebFrame.registerURLSchemeAsPrivileged('app', { secure: true })\n// Replace with\nprotocol.registerStandardSchemes(['app'], { secure: true })\n\n\n<webview>\n// Removed\nwebview.setAttribute('disableguestresize', '')\n// There is no replacement for this API\n\n// Removed\nwebview.setAttribute('guestinstance', instanceId)\n// There is no replacement for this API\n\n// Keyboard listeners no longer work on webview tag\nwebview.onkeydown = () => { /* handler */ }\nwebview.onkeyup = () => { /* handler */ }\n\n\nNode Headers URL\nThis is the URL specified as disturl in a .npmrc file or as the --dist-url\ncommand line flag when building native Node modules.\nDeprecated: https://atom.io/download/atom-shell\nReplace with: https://atom.io/download/electron\n\nBreaking API Changes (2.0)\nThe following list includes the breaking API changes made in Electron 2.0.\n\nBrowserWindow\n// Deprecated\nconst optionsA = { titleBarStyle: 'hidden-inset' }\nconst windowA = new BrowserWindow(optionsA)\n// Replace with\nconst optionsB = { titleBarStyle: 'hiddenInset' }\nconst windowB = new BrowserWindow(optionsB)\n\n\nmenu\n// Removed\nmenu.popup(browserWindow, 100, 200, 2)\n// Replaced with\nmenu.popup(browserWindow, { x: 100, y: 200, positioningItem: 2 })\n\n\nnativeImage\n// Removed\nnativeImage.toPng()\n// Replaced with\nnativeImage.toPNG()\n\n// Removed\nnativeImage.toJpeg()\n// Replaced with\nnativeImage.toJPEG()\n\n\nprocess\n\nprocess.versions.electron and process.version.chrome will be made\nread-only properties for consistency with the other process.versions\nproperties set by Node.\n\n\nwebContents\n// Removed\nwebContents.setZoomLevelLimits(1, 2)\n// Replaced with\nwebContents.setVisualZoomLevelLimits(1, 2)\n\n\nwebFrame\n// Removed\nwebFrame.setZoomLevelLimits(1, 2)\n// Replaced with\nwebFrame.setVisualZoomLevelLimits(1, 2)\n\n\n<webview>\n// Removed\nwebview.setZoomLevelLimits(1, 2)\n// Replaced with\nwebview.setVisualZoomLevelLimits(1, 2)\n\n\nDuplicate ARM Assets\nEach Electron release includes two identical ARM builds with slightly different\nfilenames, like electron-v1.7.3-linux-arm.zip and\nelectron-v1.7.3-linux-armv7l.zip. The asset with the v7l prefix was added\nto clarify to users which ARM version it supports, and to disambiguate it from\nfuture armv6l and arm64 assets that may be produced.\nThe file without the prefix is still being published to avoid breaking any\nsetups that may be consuming it. Starting at 2.0, the unprefixed file will\nno longer be published.\nFor details, see\n6986\nand\n7189.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Breaking Changes",
"doc:breaking-changes",
"tutorial:Breaking Changes",
"tutorial:breaking-changes"
]
},
{
"objectID": "tutorial-build-instructions-gn",
"title": "Build Instructions",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/development/build-instructions-gn.md",
"url": "https://electronjs.org/docs/development/build-instructions-gn",
"slug": "build-instructions-gn",
"body": "Build Instructions\nFollow the guidelines below for building Electron.\n\nPlatform prerequisites\nCheck the build prerequisites for your platform before proceeding\n\nmacOS\nLinux\nWindows\n\n\nBuild Tools\nElectron'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.\n\nGN prerequisites\nYou'll need to install depot_tools, the toolset\nused for fetching Chromium and its dependencies.\nAlso, on Windows, you'll need to set the environment variable\nDEPOT_TOOLS_WIN_TOOLCHAIN=0. To do so, open Control Panel → System and Security → System → Advanced system settings and add a system variable\nDEPOT_TOOLS_WIN_TOOLCHAIN with value 0. This tells depot_tools to use\nyour locally installed version of Visual Studio (by default, depot_tools will\ntry to download a Google-internal version that only Googlers have access to).\n\nSetting up the git cache\nIf you plan on checking out Electron more than once (for example, to have\nmultiple parallel directories checked out to different branches), using the git\ncache will speed up subsequent calls to gclient. To do this, set a\nGIT_CACHE_PATH environment variable:\n$ export GIT_CACHE_PATH=\"${HOME}/.git_cache\"\n$ mkdir -p \"${GIT_CACHE_PATH}\"\n# This will use about 16G.\n\n\nGetting the code\n$ mkdir electron && cd electron\n$ gclient config --name \"src/electron\" --unmanaged https://github.com/electron/electron\n$ gclient sync --with_branch_heads --with_tags\n# This will take a while, go get a coffee.\n\n\nInstead of https://github.com/electron/electron, you can use your own fork\nhere (something like https://github.com/<username>/electron).\n\n\nA note on pulling/pushing\nIf you intend to git pull or git push from the official electron\nrepository in the future, you now need to update the respective folder's\norigin URLs.\n$ cd src/electron\n$ git remote remove origin\n$ git remote add origin https://github.com/electron/electron\n$ git checkout master\n$ git branch --set-upstream-to=origin/master\n$ cd -\n\n📝 gclient works by checking a file called DEPS inside the\nsrc/electron folder for dependencies (like Chromium or Node.js).\nRunning gclient sync -f ensures that all dependencies required\nto build Electron match that file.\nSo, in order to pull, you'd run the following commands:\n$ cd src/electron\n$ git pull\n$ gclient sync -f\n\n\nBuilding\n$ cd src\n$ export CHROMIUM_BUILDTOOLS_PATH=`pwd`/buildtools\n$ gn gen out/Testing --args=\"import(\\\"//electron/build/args/testing.gn\\\") $GN_EXTRA_ARGS\"\n\nOr on Windows (without the optional argument):\n$ cd src\n$ set CHROMIUM_BUILDTOOLS_PATH=%cd%\\buildtools\n$ gn gen out/Testing --args=\"import(\\\"//electron/build/args/testing.gn\\\")\"\n\nThis will generate a build directory out/Testing under src/ with\nthe testing build configuration. You can replace Testing with another name,\nbut it should be a subdirectory of out.\nAlso you shouldn't have to run gn gen again—if you want to change the\nbuild arguments, you can run gn args out/Testing to bring up an editor.\nTo see the list of available build configuration options, run gn args out/Testing --list.\nFor generating Testing build config of\nElectron:\n$ gn gen out/Testing --args=\"import(\\\"//electron/build/args/testing.gn\\\") $GN_EXTRA_ARGS\"\n\nFor generating Release (aka \"non-component\" or \"static\") build config of\nElectron:\n$ gn gen out/Release --args=\"import(\\\"//electron/build/args/release.gn\\\") $GN_EXTRA_ARGS\"\n\nTo build, run ninja with the electron target:\nNota Bene: This will also take a while and probably heat up your lap.\nFor the testing configuration:\n$ ninja -C out/Testing electron\n\nFor the release configuration:\n$ ninja -C out/Release electron\n\nThis will build all of what was previously 'libchromiumcontent' (i.e. the\ncontent/ directory of chromium and its dependencies, incl. WebKit and V8),\nso it will take a while.\nThe built executable will be under ./out/Testing:\n$ ./out/Testing/Electron.app/Contents/MacOS/Electron\n# or, on Windows\n$ ./out/Testing/electron.exe\n# or, on Linux\n$ ./out/Testing/electron\n\n\nPackaging\nOn linux, first strip the debugging and symbol information:\nelectron/script/strip-binaries.py -d out/Release\n\nTo package the electron build as a distributable zip file:\nninja -C out/Release electron:electron_dist_zip\n\n\nCross-compiling\nTo compile for a platform that isn't the same as the one you're building on,\nset the target_cpu and target_os GN arguments. For example, to compile an\nx86 target from an x64 host, specify target_cpu = \"x86\" in gn args.\n$ gn gen out/Testing-x86 --args='... target_cpu = \"x86\"'\n\nNot all combinations of source and target CPU/OS are supported by Chromium.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nHostTargetStatusWindows x64Windows arm64ExperimentalWindows x64Windows x86Automatically testedLinux x64Linux x86Automatically tested\nIf you test other combinations and find them to work, please update this document :)\nSee the GN reference for allowable values of target_os\nand target_cpu.\n\nWindows on Arm (experimental)\nTo 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.\nset ELECTRON_BUILDING_WOA=1\ngclient sync -f --with_branch_heads --with_tags\n\nOr (if using PowerShell):\n$env:ELECTRON_BUILDING_WOA=1\ngclient sync -f --with_branch_heads --with_tags\n\nNext, run gn gen as above with target_cpu=\"arm64\".\n\nTests\nTo run the tests, you'll first need to build the test modules against the\nsame version of Node.js that was built as part of the build process. To\ngenerate build headers for the modules to compile against, run the following\nunder src/ directory.\n$ ninja -C out/Testing third_party/electron_node:headers\n\nYou can now run the tests.\nIf you're debugging something, it can be helpful to pass some extra flags to\nthe Electron binary:\n$ npm run test -- \\\n --enable-logging -g 'BrowserWindow module'\n\n\nSharing the git cache between multiple machines\nIt is possible to share the gclient git cache with other machines by exporting it as\nSMB share on linux, but only one process/machine can be using the cache at a\ntime. The locks created by git-cache script will try to prevent this, but it may\nnot work perfectly in a network.\nOn Windows, SMBv2 has a directory cache that will cause problems with the git\ncache script, so it is necessary to disable it by setting the registry key\nHKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Services\\Lanmanworkstation\\Parameters\\DirectoryCacheLifetime\n\nto 0. More information: https://stackoverflow.com/a/9935126\nThis can be set quickly in powershell (ran as administrator):\nNew-ItemProperty -Path \"HKLM:\\System\\CurrentControlSet\\Services\\Lanmanworkstation\\Parameters\" -Name DirectoryCacheLifetime -Value 0 -PropertyType DWORD -Force\n\n\nTroubleshooting\n\ngclient sync complains about rebase\nIf 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:\n2> Conflict while rebasing this branch.\n2> Fix the conflict and run gclient again.\n2> See man git-rebase for details.\n\nIf there are no git conflicts or rebases in src/electron, you may need to abort a git am in src:\n$ cd ../\n$ git am --abort\n$ cd electron\n$ gclient sync -f\n\n\nI'm being asked for a username/password for chromium-internal.googlesource.com\nIf 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\nDEPOT_TOOLS_WIN_TOOLCHAIN with value 0. This tells depot_tools to use\nyour locally installed version of Visual Studio (by default, depot_tools will\ntry to download a Google-internal version that only Googlers have access to).",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Build Instructions",
"doc:build-instructions-gn",
"tutorial:Build Instructions",
"tutorial:build-instructions-gn"
]
},
{
"objectID": "tutorial-build-instructions-linux",
"title": "Build Instructions (Linux)",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/development/build-instructions-linux.md",
"url": "https://electronjs.org/docs/development/build-instructions-linux",
"slug": "build-instructions-linux",
"body": "Build Instructions (Linux)\nFollow the guidelines below for building Electron on Linux.\n\nPrerequisites\n\n\nAt least 25GB disk space and 8GB RAM.\n\n\nPython 2.7.x. Some distributions like CentOS 6.x still use Python 2.6.x\nso you may need to check your Python version with python -V.\nPlease also ensure that your system and Python version support at least TLS 1.2.\nFor a quick test, run the following script:\n$ npx @electron/check-python-tls\n\nIf the script returns that your configuration is using an outdated security\nprotocol, use your system's package manager to update Python to the latest\nversion in the 2.7.x branch. Alternatively, visit https://www.python.org/downloads/\nfor detailed instructions.\n\n\nNode.js. There are various ways to install Node. You can download\nsource code from nodejs.org and compile it.\nDoing so permits installing Node on your own home directory as a standard user.\nOr try repositories such as NodeSource.\n\n\nclang 3.4 or later.\n\n\nDevelopment headers of GTK 3 and libnotify.\n\n\nOn Ubuntu, install the following libraries:\n$ sudo apt-get install build-essential clang libdbus-1-dev libgtk-3-dev \\\n libnotify-dev libgnome-keyring-dev \\\n libasound2-dev libcap-dev libcups2-dev libxtst-dev \\\n libxss1 libnss3-dev gcc-multilib g++-multilib curl \\\n gperf bison python-dbusmock openjdk-8-jre\n\nOn RHEL / CentOS, install the following libraries:\n$ sudo yum install clang dbus-devel gtk3-devel libnotify-devel \\\n libgnome-keyring-devel xorg-x11-server-utils libcap-devel \\\n cups-devel libXtst-devel alsa-lib-devel libXrandr-devel \\\n nss-devel python-dbusmock openjdk-8-jre\n\nOn Fedora, install the following libraries:\n$ sudo dnf install clang dbus-devel gtk3-devel libnotify-devel \\\n libgnome-keyring-devel xorg-x11-server-utils libcap-devel \\\n cups-devel libXtst-devel alsa-lib-devel libXrandr-devel \\\n nss-devel python-dbusmock openjdk-8-jre\n\nOn Arch Linux / Manjaro, install the following libraries:\n$ sudo pacman -Syu base-devel clang libdbus gtk2 libnotify \\\n libgnome-keyring alsa-lib libcap libcups libxtst \\\n libxss nss gcc-multilib curl gperf bison \\\n python2 python-dbusmock jdk8-openjdk\n\nOther distributions may offer similar packages for installation via package\nmanagers such as pacman. Or one can compile from source code.\n\nCross compilation\nIf you want to build for an arm target you should also install the following\ndependencies:\n$ sudo apt-get install libc6-dev-armhf-cross linux-libc-dev-armhf-cross \\\n g++-arm-linux-gnueabihf\n\nSimilarly for arm64, install the following:\n$ sudo apt-get install libc6-dev-arm64-cross linux-libc-dev-arm64-cross \\\n g++-aarch64-linux-gnu\n\nAnd to cross-compile for arm or ia32 targets, you should pass the\ntarget_cpu parameter to gn gen:\n$ gn gen out/Testing --args='import(...) target_cpu=\"arm\"'\n\n\nBuilding\nSee Build Instructions: GN\n\nTroubleshooting\n\nError While Loading Shared Libraries: libtinfo.so.5\nPrebuilt clang will try to link to libtinfo.so.5. Depending on the host\narchitecture, symlink to appropriate libncurses:\n$ sudo ln -s /usr/lib/libncurses.so.5 /usr/lib/libtinfo.so.5\n\n\nAdvanced topics\nThe default building configuration is targeted for major desktop Linux\ndistributions. To build for a specific distribution or device, the following\ninformation may help you.\n\nUsing system clang instead of downloaded clang binaries\nBy default Electron is built with prebuilt\nclang binaries provided by the\nChromium project. If for some reason you want to build with the clang\ninstalled in your system, you can specify the clang_base_path argument in the\nGN args.\nFor example if you installed clang under /usr/local/bin/clang:\n$ gn gen out/Testing --args='import(\"//electron/build/args/testing.gn\") clang_base_path = \"/usr/local/bin\"'\n\n\nUsing compilers other than clang\nBuilding Electron with compilers other than clang is not supported.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Build Instructions (Linux)",
"doc:build-instructions-linux",
"tutorial:Build Instructions (Linux)",
"tutorial:build-instructions-linux"
]
},
{
"objectID": "tutorial-build-instructions-macos",
"title": "Build Instructions (macOS)",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/development/build-instructions-macos.md",
"url": "https://electronjs.org/docs/development/build-instructions-macos",
"slug": "build-instructions-macos",
"body": "Build Instructions (macOS)\nFollow the guidelines below for building Electron on macOS.\n\nPrerequisites\n\nmacOS >= 10.11.6\nXcode >= 9.0.0\nnode.js (external)\nPython 2.7 with support for TLS 1.2\n\n\nPython\nPlease also ensure that your system and Python version support at least TLS 1.2.\nThis depends on both your version of macOS and Python. For a quick test, run:\n$ npx @electron/check-python-tls\n\nIf the script returns that your configuration is using an outdated security\nprotocol, you can either update macOS to High Sierra or install a new version\nof Python 2.7.x. To upgrade Python, use Homebrew:\n$ brew install python@2 && brew link python@2 --force\n\nIf you are using Python as provided by Homebrew, you also need to install\nthe following Python modules:\n\npyobjc\n\nYou can use pip to install it:\n$ pip install pyobjc\n\n\nmacOS SDK\nIf you're developing Electron and don't plan to redistribute your\ncustom Electron build, you may skip this section.\nOfficial Electron builds are built with Xcode 12.2, and the macOS 11.0 SDK. Building with a newer SDK works too, but the releases currently use the 11.0 SDK.\n\nBuilding Electron\nSee Build Instructions: GN.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Build Instructions (macOS)",
"doc:build-instructions-macos",
"tutorial:Build Instructions (macOS)",
"tutorial:build-instructions-macos"
]
},
{
"objectID": "tutorial-build-instructions-windows",
"title": "Build Instructions (Windows)",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/development/build-instructions-windows.md",
"url": "https://electronjs.org/docs/development/build-instructions-windows",
"slug": "build-instructions-windows",
"body": "Build Instructions (Windows)\nFollow the guidelines below for building Electron on Windows.\n\nPrerequisites\n\nWindows 10 / Server 2012 R2 or higher\nVisual Studio 2017 15.7.2 or higher - download VS 2019 Community Edition for\nfree\nSee the Chromium build documentation for more details on which Visual Studio\ncomponents are required.\nIf your Visual Studio is installed in a directory other than the default, you'll need to\nset a few environment variables to point the toolchains to your installation path.\nvs2019_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:.\nWINDOWSSDKDIR = DRIVE:\\path\\to\\Windows Kits\\10, replacing DRIVE: with the drive that Windows Kits is on. Often, this will be C:.\n\nPython for Windows (pywin32) Extensions\nis also needed in order to run the build process.\n\nNode.js\nGit\nDebugging Tools for Windows of Windows SDK 10.0.15063.468 if you plan on\ncreating a full distribution since symstore.exe is used for creating a symbol\nstore from .pdb files.\nDifferent versions of the SDK can be installed side by side. To install the\nSDK, open Visual Studio Installer, select\nChange → Individual Components, scroll down and select the appropriate\nWindows SDK to install. Another option would be to look at the\nWindows SDK and emulator archive\nand download the standalone version of the SDK respectively.\nThe SDK Debugging Tools must also be installed. If the Windows 10 SDK was installed\nvia the Visual Studio installer, then they can be installed by going to:\nControl Panel → Programs → Programs and Features → Select the \"Windows Software Development Kit\" →\nChange → Change → Check \"Debugging Tools For Windows\" → Change.\nOr, you can download the standalone SDK installer and use it to install the Debugging Tools.\n\n\nIf you don't currently have a Windows installation,\ndev.microsoftedge.com\nhas timebombed versions of Windows that you can use to build Electron.\nBuilding Electron is done entirely with command-line scripts and cannot be done\nwith Visual Studio. You can develop Electron with any editor but support for\nbuilding with Visual Studio will come in the future.\nNote: Even though Visual Studio is not used for building, it's still\nrequired because we need the build toolchains it provides.\n\nExclude source tree from Windows Security\nWindows Security doesn't like one of the files in the Chromium source code\n(see https://crbug.com/441184), so it will constantly delete it, causing gclient sync issues.\nYou can exclude the source tree from being monitored by Windows Security by\nfollowing these instructions.\n\nBuilding\nSee Build Instructions: GN\n\n32bit Build\nTo build for the 32bit target, you need to pass target_cpu = \"x86\" as a GN\narg. You can build the 32bit target alongside the 64bit target by using a\ndifferent output directory for GN, e.g. out/Release-x86, with different\narguments.\n$ gn gen out/Release-x86 --args=\"import(\\\"//electron/build/args/release.gn\\\") target_cpu=\\\"x86\\\"\"\n\nThe other building steps are exactly the same.\n\nVisual Studio project\nTo generate a Visual Studio project, you can pass the --ide=vs2017 parameter\nto gn gen:\n$ gn gen out/Testing --ide=vs2017\n\n\nTroubleshooting\n\nCommand xxxx not found\nIf you encountered an error like Command xxxx not found, you may try to use\nthe VS2015 Command Prompt console to execute the build scripts.\n\nFatal internal compiler error: C1001\nMake sure you have the latest Visual Studio update installed.\n\nLNK1181: cannot open input file 'kernel32.lib'\nTry reinstalling 32bit Node.js.\n\nError: ENOENT, stat 'C:\\Users\\USERNAME\\AppData\\Roaming\\npm'\nCreating that directory should fix the problem:\n$ mkdir ~\\AppData\\Roaming\\npm\n\n\nnode-gyp is not recognized as an internal or external command\nYou may get this error if you are using Git Bash for building, you should use\nPowerShell or VS2015 Command Prompt instead.\n\ncannot create directory at '...': Filename too long\nnode.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:\n$ git config --system core.longpaths true\n\n\nerror: use of undeclared identifier 'DefaultDelegateCheckMode'\nThis 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.\n\nImportError: No module named win32file\nMake sure you have installed pywin32 with pip install pywin32.\n\nBuild Scripts Hang Until Keypress\nThis bug is a \"feature\" of Windows' command prompt. It happens when clicking inside the prompt window with\nQuickEdit enabled and is intended to allow selecting and copying output text easily.\nSince each accidental click will pause the build process, you might want to disable this\nfeature in the command prompt properties.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Build Instructions (Windows)",
"doc:build-instructions-windows",
"tutorial:Build Instructions (Windows)",
"tutorial:build-instructions-windows"
]
},
{
"objectID": "tutorial-build-system-overview",
"title": "Build System Overview",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/development/build-system-overview.md",
"url": "https://electronjs.org/docs/development/build-system-overview",
"slug": "build-system-overview",
"body": "Build System Overview\nElectron uses GN for project generation and\nninja for building. Project configurations can\nbe found in the .gn and .gni files.\n\nGN Files\nThe following gn files contain the main rules for building Electron:\n\nBUILD.gn defines how Electron itself is built and\nincludes the default configurations for linking with Chromium.\nbuild/args/{debug,release,all}.gn contain the default build arguments for\nbuilding Electron.\n\n\nComponent Build\nSince Chromium is quite a large project, the final linking stage can take\nquite a few minutes, which makes it hard for development. In order to solve\nthis, Chromium introduced the \"component build\", which builds each component as\na separate shared library, making linking very quick but sacrificing file size\nand performance.\nElectron inherits this build option from Chromium. In Debug builds, the\nbinary will be linked to a shared library version of Chromium's components to\nachieve fast linking time; for Release builds, the binary will be linked to\nthe static library versions, so we can have the best possible binary size and\nperformance.\n\nTests\nNB this section is out of date and contains information that is no longer\nrelevant to the GN-built electron.\nTest your changes conform to the project coding style using:\n$ npm run lint\n\nTest functionality using:\n$ npm test\n\nWhenever you make changes to Electron source code, you'll need to re-run the\nbuild before the tests:\n$ npm run build && npm test\n\nYou can make the test suite run faster by isolating the specific test or block\nyou're currently working on using Mocha's\nexclusive tests feature. Append\n.only to any describe or it function call:\ndescribe.only('some feature', () => {\n // ... only tests in this block will be run\n})\n\nAlternatively, you can use mocha's grep option to only run tests matching the\ngiven regular expression pattern:\n$ npm test -- --grep child_process\n\nTests that include native modules (e.g. runas) can't be executed with the\ndebug build (see #2558 for\ndetails), but they will work with the release build.\nTo run the tests with the release build use:\n$ npm test -- -R\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Build System Overview",
"doc:build-system-overview",
"tutorial:Build System Overview",
"tutorial:build-system-overview"
]
},
{
"objectID": "tutorial-chromium-development",
"title": "Chromium Development",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/development/chromium-development.md",
"url": "https://electronjs.org/docs/development/chromium-development",
"slug": "chromium-development",
"body": "Chromium Development\n\nA collection of resources for learning about Chromium and tracking its development\n\n\n@ChromiumDev on Twitter\n@googlechrome on Twitter\nBlog\nCode Search\nSource Code\nDevelopment Calendar and Release Info\nDiscussion Groups\n\nSee also V8 Development",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Chromium Development",
"doc:chromium-development",
"tutorial:Chromium Development",
"tutorial:chromium-development"
]
},
{
"objectID": "tutorial-clang-format",
"title": "Using clang-format on C++ Code",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/development/clang-format.md",
"url": "https://electronjs.org/docs/development/clang-format",
"slug": "clang-format",
"body": "Using clang-format on C++ Code\nclang-format is a tool to\nautomatically format C/C++/Objective-C code, so that developers don't need to\nworry about style issues during code reviews.\nIt is highly recommended to format your changed C++ code before opening pull\nrequests, which will save you and the reviewers' time.\nYou can install clang-format and git-clang-format via\nnpm install -g clang-format.\nTo automatically format a file according to Electron C++ code style, run\nclang-format -i path/to/electron/file.cc. It should work on macOS/Linux/Windows.\nThe workflow to format your changed code:\n\nMake codes changes in Electron repository.\nRun git add your_changed_file.cc.\nRun git-clang-format, and you will probably see modifications in\nyour_changed_file.cc, these modifications are generated from clang-format.\nRun git add your_changed_file.cc, and commit your change.\nNow the branch is ready to be opened as a pull request.\n\nIf you want to format the changed code on your latest git commit (HEAD), you can\nrun git-clang-format HEAD~1. See git-clang-format -h for more details.\n\nEditor Integration\nYou can also integrate clang-format directly into your favorite editors.\nFor further guidance on setting up editor integration, see these pages:\n\nAtom\nVim & Emacs\nVisual Studio Code\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Using clang-format on C++ Code",
"doc:clang-format",
"tutorial:Using clang-format on C++ Code",
"tutorial:clang-format"
]
},
{
"objectID": "tutorial-clang-tidy",
"title": "Using clang-tidy on C++ Code",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/development/clang-tidy.md",
"url": "https://electronjs.org/docs/development/clang-tidy",
"slug": "clang-tidy",
"body": "Using clang-tidy on C++ Code\nclang-tidy is a tool to\nautomatically check C/C++/Objective-C code for style violations, programming\nerrors, and best practices.\nElectron's clang-tidy integration is provided as a linter script which can\nbe run with npm run lint:clang-tidy. While clang-tidy checks your on-disk\nfiles, you need to have built Electron so that it knows which compiler flags\nwere used. There is one required option for the script --output-dir, which\ntells the script which build directory to pull the compilation information\nfrom. A typical usage would be:\nnpm run lint:clang-tiy --out-dir ../out/Testing\nWith no filenames provided, all C/C++/Objective-C files will be checked.\nYou can provide a list of files to be checked by passing the filenames after\nthe options:\nnpm run lint:clang-tiy --out-dir ../out/Testing shell/browser/api/electron_api_app.cc\nWhile clang-tidy has a\nlong list\nof possible checks, in Electron only a few are enabled by default. At the\nmoment Electron doesn't have a .clang-tidy config, so clang-tidy will\nfind the one from Chromium at src/.clang-tidy and use the checks which\nChromium has enabled. You can change which checks are run by using the\n--checks= option. This is passed straight through to clang-tidy, so see\nits documentation for full details. Wildcards can be used, and checks can\nbe disabled by prefixing a -. By default any checks listed are added to\nthose in .clang-tidy, so if you'd like to limit the checks to specific\nones you should first exclude all checks then add back what you want, like\n--checks=-*,performance*.\nRunning clang-tidy is rather slow - internally it compiles each file and\nthen runs the checks so it will always be some factor slower than compilation.\nWhile you can use parallel runs to speed it up using the --jobs|-j option,\nclang-tidy also uses a lot of memory during its checks, so it can easily\nrun into out-of-memory errors. As such the default number of jobs is one.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Using clang-tidy on C++ Code",
"doc:clang-tidy",
"tutorial:Using clang-tidy on C++ Code",
"tutorial:clang-tidy"
]
},
{
"objectID": "tutorial-code-signing",
"title": "Code Signing",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/code-signing.md",
"url": "https://electronjs.org/docs/tutorial/code-signing",
"slug": "code-signing",
"body": "Code Signing\nCode signing is a security technology that you use to certify that an app was\ncreated by you.\nOn macOS the system can detect any change to the app, whether the change is\nintroduced accidentally or by malicious code.\nOn Windows, the system assigns a trust level to your code signing certificate\nwhich if you don't have, or if your trust level is low, will cause security\ndialogs to appear when users start using your application. Trust level builds\nover time so it's better to start code signing as early as possible.\nWhile it is possible to distribute unsigned apps, it is not recommended. Both\nWindows and macOS will, by default, prevent either the download or the execution\nof unsigned applications. Starting with macOS Catalina (version 10.15), users\nhave to go through multiple manual steps to open unsigned applications.\n\nAs you can see, users get two options: Move the app straight to the trash or\ncancel running it. You don't want your users to see that dialog.\nIf you are building an Electron app that you intend to package and distribute,\nit should be code-signed.\n\nSigning & notarizing macOS builds\nProperly preparing macOS applications for release requires two steps: First, the\napp needs to be code-signed. Then, the app needs to be uploaded to Apple for a\nprocess called \"notarization\", where automated systems will further verify that\nyour app isn't doing anything to endanger its users.\nTo start the process, ensure that you fulfill the requirements for signing and\nnotarizing your app:\n\nEnroll in the Apple Developer Program (requires an annual fee)\nDownload and install Xcode - this requires a computer running macOS\nGenerate, download, and install signing certificates\n\nElectron's ecosystem favors configuration and freedom, so there are multiple\nways to get your application signed and notarized.\n\nelectron-forge\nIf you're using Electron's favorite build tool, getting your application signed\nand notarized requires a few additions to your configuration. Forge is a\ncollection of the official Electron tools, using electron-packager,\nelectron-osx-sign, and electron-notarize under the hood.\nLet's take a look at an example configuration with all required fields. Not all\nof them are required: the tools will be clever enough to automatically find a\nsuitable identity, for instance, but we recommend that you are explicit.\n{\n \"name\": \"my-app\",\n \"version\": \"0.0.1\",\n \"config\": {\n \"forge\": {\n \"packagerConfig\": {\n \"osxSign\": {\n \"identity\": \"Developer ID Application: Felix Rieseberg (LT94ZKYDCJ)\",\n \"hardened-runtime\": true,\n \"entitlements\": \"entitlements.plist\",\n \"entitlements-inherit\": \"entitlements.plist\",\n \"signature-flags\": \"library\"\n },\n \"osxNotarize\": {\n \"appleId\": \"felix@felix.fun\",\n \"appleIdPassword\": \"my-apple-id-password\",\n }\n }\n }\n }\n}\n\nThe plist file referenced here needs the following macOS-specific entitlements\nto assure the Apple security mechanisms that your app is doing these things\nwithout meaning any harm:\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n <dict>\n <key>com.apple.security.cs.allow-jit</key>\n <true/>\n <key>com.apple.security.cs.allow-unsigned-executable-memory</key>\n <true/>\n <key>com.apple.security.cs.debugger</key>\n <true/>\n </dict>\n</plist>\n\nTo see all of this in action, check out Electron Fiddle's source code,\nespecially its electron-forge configuration\nfile.\nIf you plan to access the microphone or camera within your app using Electron's APIs, you'll also\nneed to add the following entitlements:\n<key>com.apple.security.device.audio-input</key>\n<true/>\n<key>com.apple.security.device.camera</key>\n<true/>\n\nIf these are not present in your app's entitlements when you invoke, for example:\nconst { systemPreferences } = require('electron')\n\nconst microphone = systemPreferences.askForMediaAccess('microphone')\n\nYour app may crash. See the Resource Access section in Hardened Runtime for more information and entitlements you may need.\n\nelectron-builder\nElectron Builder comes with a custom solution for signing your application. You\ncan find its documentation here.\n\nelectron-packager\nIf you're not using an integrated build pipeline like Forge or Builder, you\nare likely using electron-packager, which includes electron-osx-sign and\nelectron-notarize.\nIf you're using Packager's API, you can pass in configuration that both signs\nand notarizes your\napplication.\nconst packager = require('electron-packager')\n\npackager({\n dir: '/path/to/my/app',\n osxSign: {\n identity: 'Developer ID Application: Felix Rieseberg (LT94ZKYDCJ)',\n 'hardened-runtime': true,\n entitlements: 'entitlements.plist',\n 'entitlements-inherit': 'entitlements.plist',\n 'signature-flags': 'library'\n },\n osxNotarize: {\n appleId: 'felix@felix.fun',\n appleIdPassword: 'my-apple-id-password'\n }\n})\n\nThe plist file referenced here needs the following macOS-specific entitlements\nto assure the Apple security mechanisms that your app is doing these things\nwithout meaning any harm:\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n <dict>\n <key>com.apple.security.cs.allow-jit</key>\n <true/>\n <key>com.apple.security.cs.allow-unsigned-executable-memory</key>\n <true/>\n <key>com.apple.security.cs.debugger</key>\n <true/>\n </dict>\n</plist>\n\n\nMac App Store\nSee the Mac App Store Guide.\n\nSigning Windows builds\nBefore signing Windows builds, you must do the following:\n\nGet a Windows Authenticode code signing certificate (requires an annual fee)\nInstall Visual Studio to get the signing utility (the free Community\nEdition is enough)\n\nYou can get a code signing certificate from a lot of resellers. Prices vary, so\nit may be worth your time to shop around. Popular resellers include:\n\ndigicert\nSectigo\nGoDaddy\nAmongst others, please shop around to find one that suits your needs, Google\nis your friend 😄\n\nThere are a number of tools for signing your packaged app:\n\nelectron-winstaller will generate an installer for windows and sign it for\nyou\nelectron-forge can sign installers it generates through the\nSquirrel.Windows or MSI targets.\nelectron-builder can sign some of its windows targets\n\n\nWindows Store\nSee the Windows Store Guide.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Code Signing",
"doc:code-signing",
"tutorial:Code Signing",
"tutorial:code-signing"
]
},
{
"objectID": "tutorial-coding-style",
"title": "Coding Style",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/development/coding-style.md",
"url": "https://electronjs.org/docs/development/coding-style",
"slug": "coding-style",
"body": "Coding Style\nThese are the style guidelines for coding in Electron.\nYou can run npm run lint to show any style issues detected by cpplint and\neslint.\n\nGeneral Code\n\nEnd files with a newline.\nPlace requires in the following order:\nBuilt in Node Modules (such as path)\nBuilt in Electron Modules (such as ipc, app)\nLocal Modules (using relative paths)\n\nPlace class properties in the following order:\nClass methods and properties (methods starting with a @)\nInstance methods and properties\n\nAvoid platform-dependent code:\nUse path.join() to concatenate filenames.\nUse os.tmpdir() rather than /tmp when you need to reference the\ntemporary directory.\n\nUsing a plain return when returning explicitly at the end of a function.\nNot return null, return undefined, null or undefined\n\n\n\nC++ and Python\nFor C++ and Python, we follow Chromium's Coding\nStyle. You can use\nclang-format to format the C++ code automatically. There is\nalso a script script/cpplint.py to check whether all files conform.\nThe Python version we are using now is Python 2.7.\nThe C++ code uses a lot of Chromium's abstractions and types, so it's\nrecommended to get acquainted with them. A good place to start is\nChromium's Important Abstractions and Data Structures\ndocument. The document mentions some special types, scoped types (that\nautomatically release their memory when going out of scope), logging mechanisms\netc.\n\nDocumentation\n\nWrite remark markdown style.\n\nYou can run npm run lint-docs to ensure that your documentation changes are\nformatted correctly.\n\nJavaScript\n\nWrite standard JavaScript style.\nFile names should be concatenated with - instead of _, e.g.\nfile-name.js rather than file_name.js, because in\ngithub/atom module names are usually in\nthe module-name form. This rule only applies to .js files.\nUse newer ES6/ES2015 syntax where appropriate\nconst\nfor requires and other constants. If the value is a primitive, use uppercase naming (eg const NUMBER_OF_RETRIES = 5).\nlet\nfor defining variables\nArrow functions\ninstead of function () { }\nTemplate literals\ninstead of string concatenation using +\n\n\n\nNaming Things\nElectron APIs uses the same capitalization scheme as Node.js:\n\nWhen the module itself is a class like BrowserWindow, use PascalCase.\nWhen the module is a set of APIs, like globalShortcut, use camelCase.\nWhen the API is a property of object, and it is complex enough to be in a\nseparate chapter like win.webContents, use mixedCase.\nFor other non-module APIs, use natural titles, like <webview> Tag or\nProcess Object.\n\nWhen creating a new API, it is preferred to use getters and setters instead of\njQuery's one-function style. For example, .getText() and .setText(text)\nare preferred to .text([text]). There is a\ndiscussion on this.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Coding Style",
"doc:coding-style",
"tutorial:Coding Style",
"tutorial:coding-style"
]
},
{
"objectID": "tutorial-context-isolation",
"title": "Context Isolation",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/context-isolation.md",
"url": "https://electronjs.org/docs/tutorial/context-isolation",
"slug": "context-isolation",
"body": "Context Isolation\n\nWhat is it?\nContext 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.\nThis 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.\nEvery single application should have context isolation enabled and from Electron 12 it will be enabled by default.\n\nHow do I enable it?\nFrom Electron 12, it will be enabled by default. For lower versions it is an option in the webPreferences option when constructing new BrowserWindow's.\nconst mainWindow = new BrowserWindow({\n webPreferences: {\n contextIsolation: true\n }\n})\n\n\nMigration\n\nI used to provide APIs from my preload script using window.X = apiObject now what?\n\nExposing 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.\nBefore: With context isolation disabled\nwindow.myAPI = {\n doAThing: () => {}\n}\n\nAfter: With context isolation enabled\nconst { contextBridge } = require('electron')\n\ncontextBridge.exposeInMainWorld('myAPI', {\n doAThing: () => {}\n})\n\nThe 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.\nYou 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.\n\nSecurity Considerations\nJust enabling contextIsolation and using contextBridge does not automatically mean that everything you do is safe. For instance this code is unsafe.\n// ❌ Bad code\ncontextBridge.exposeInMainWorld('myAPI', {\n send: ipcRenderer.send\n})\n\nIt 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.\n// ✅ Good code\ncontextBridge.exposeInMainWorld('myAPI', {\n loadPreferences: () => ipcRenderer.invoke('load-prefs')\n})\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Context Isolation",
"doc:context-isolation",
"tutorial:Context Isolation",
"tutorial:context-isolation"
]
},
{
"objectID": "tutorial-dark-mode",
"title": "Dark Mode",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/dark-mode.md",
"url": "https://electronjs.org/docs/tutorial/dark-mode",
"slug": "dark-mode",
"body": "Dark Mode\n\nOverview\n\nAutomatically update the native interfaces\n\"Native interfaces\" include the file picker, window border, dialogs, context\nmenus, and more - anything where the UI comes from your operating system and\nnot from your app. The default behavior is to opt into this automatic theming\nfrom the OS.\n\nAutomatically update your own interfaces\nIf your app has its own dark mode, you should toggle it on and off in sync with\nthe system's dark mode setting. You can do this by using the\nprefer-color-scheme CSS media query.\n\nManually update your own interfaces\nIf you want to manually switch between light/dark modes, you can do this by\nsetting the desired mode in the\nthemeSource\nproperty of the nativeTheme module. This property's value will be propagated\nto your Renderer process. Any CSS rules related to prefers-color-scheme will\nbe updated accordingly.\n\nmacOS settings\nIn macOS 10.14 Mojave, Apple introduced a new system-wide dark mode\nfor all macOS computers. If your Electron app has a dark mode, you can make it\nfollow the system-wide dark mode setting using\nthe nativeTheme api.\nIn macOS 10.15 Catalina, Apple introduced a new \"automatic\" dark mode option\nfor all macOS computers. In order for the nativeTheme.shouldUseDarkColors and\nTray APIs to work correctly in this mode on Catalina, you need to use Electron\n>=7.0.0, or set NSRequiresAquaSystemAppearance to false in your\nInfo.plist file for older versions. Both Electron Packager\nand Electron Forge have a\ndarwinDarkModeSupport option\nto automate the Info.plist changes during app build time.\nIf you wish to opt-out while using Electron > 8.0.0, you must\nset the NSRequiresAquaSystemAppearance key in the Info.plist file to\ntrue. Please note that Electron 8.0.0 and above will not let you opt-out\nof this theming, due to the use of the macOS 10.14 SDK.\n\nExample\nWe'll start with a working application from the\nQuick Start Guide and add functionality gradually.\nFirst, let's edit our interface so users can toggle between light and dark\nmodes. This basic UI contains buttons to change the nativeTheme.themeSource\nsetting and a text element indicating which themeSource value is selected.\nBy default, Electron follows the system's dark mode preference, so we\nwill hardcode the theme source as \"System\".\nAdd the following lines to the index.html file:\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"UTF-8\">\n <title>Hello World!</title>\n <meta http-equiv=\"Content-Security-Policy\" content=\"script-src 'self' 'unsafe-inline';\" />\n <link rel=\"stylesheet\" type=\"text/css\" href=\"./styles.css\">\n</head>\n<body>\n <h1>Hello World!</h1>\n <p>Current theme source: <strong id=\"theme-source\">System</strong></p>\n\n <button id=\"toggle-dark-mode\">Toggle Dark Mode</button>\n <button id=\"reset-to-system\">Reset to System Theme</button>\n\n <script src=\"renderer.js\"></script>\n </body>\n</body>\n</html>\n\nNext, add event listeners\nthat listen for click events on the toggle buttons. Because the nativeTheme\nmodule only exposed in the Main process, you need to set up each listener's\ncallback to use IPC to send messages to and handle responses from the Main\nprocess:\n\nwhen the \"Toggle Dark Mode\" button is clicked, we send the\ndark-mode:toggle message (event) to tell the Main process to trigger a theme\nchange, and update the \"Current Theme Source\" label in the UI based on the\nresponse from the Main process.\nwhen the \"Reset to System Theme\" button is clicked, we send the\ndark-mode:system message (event) to tell the Main process to use the system\ncolor scheme, and update the \"Current Theme Source\" label to System.\n\nTo add listeners and handlers, add the following lines to the renderer.js file:\nconst { ipcRenderer } = require('electron')\n\ndocument.getElementById('toggle-dark-mode').addEventListener('click', async () => {\n const isDarkMode = await ipcRenderer.invoke('dark-mode:toggle')\n document.getElementById('theme-source').innerHTML = isDarkMode ? 'Dark' : 'Light'\n})\n\ndocument.getElementById('reset-to-system').addEventListener('click', async () => {\n await ipcRenderer.invoke('dark-mode:system')\n document.getElementById('theme-source').innerHTML = 'System'\n})\n\nIf you run your code at this point, you'll see that your buttons don't do\nanything just yet, and your Main process will output an error like this when\nyou click on your buttons:\nError occurred in handler for 'dark-mode:toggle': No handler registered for 'dark-mode:toggle'\nThis is expected — we haven't actually touched any nativeTheme code yet.\nNow that we're done wiring the IPC from the Renderer's side, the next step\nis to update the main.js file to handle events from the Renderer process.\nDepending on the received event, we update the\nnativeTheme.themeSource\nproperty to apply the desired theme on the system's native UI elements\n(e.g. context menus) and propagate the preferred color scheme to the Renderer\nprocess:\n\nUpon receiving dark-mode:toggle, we check if the dark theme is currently\nactive using the nativeTheme.shouldUseDarkColors property, and set the\nthemeSource to the opposite theme.\nUpon receiving dark-mode:system, we reset the themeSource to system.\n\nconst { app, BrowserWindow, ipcMain, nativeTheme } = require('electron')\n\nfunction createWindow () {\n const win = new BrowserWindow({\n width: 800,\n height: 600,\n webPreferences: {\n nodeIntegration: true\n }\n })\n\n win.loadFile('index.html')\n\n ipcMain.handle('dark-mode:toggle', () => {\n if (nativeTheme.shouldUseDarkColors) {\n nativeTheme.themeSource = 'light'\n } else {\n nativeTheme.themeSource = 'dark'\n }\n return nativeTheme.shouldUseDarkColors\n })\n\n ipcMain.handle('dark-mode:system', () => {\n nativeTheme.themeSource = 'system'\n })\n}\n\napp.whenReady().then(createWindow)\n\napp.on('window-all-closed', () => {\n if (process.platform !== 'darwin') {\n app.quit()\n }\n})\n\napp.on('activate', () => {\n if (BrowserWindow.getAllWindows().length === 0) {\n createWindow()\n }\n})\n\nThe final step is to add a bit of styling to enable dark mode for the web parts\nof the UI by leveraging the prefers-color-scheme CSS\nattribute. The value of prefers-color-scheme will follow your\nnativeTheme.themeSource setting.\nCreate a styles.css file and add the following lines:\n@media (prefers-color-scheme: dark) {\n body { background: #333; color: white; }\n}\n\n@media (prefers-color-scheme: light) {\n body { background: #ddd; color: black; }\n}\n\nAfter launching the Electron application, you can change modes or reset the\ntheme to system default by clicking corresponding buttons:\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Dark Mode",
"doc:dark-mode",
"tutorial:Dark Mode",
"tutorial:dark-mode"
]
},
{
"objectID": "tutorial-debug-instructions-windows",
"title": "Debugging on Windows",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/development/debug-instructions-windows.md",
"url": "https://electronjs.org/docs/development/debug-instructions-windows",
"slug": "debug-instructions-windows",
"body": "Debugging on Windows\nIf you experience crashes or issues in Electron that you believe are not caused\nby your JavaScript application, but instead by Electron itself, debugging can\nbe a little bit tricky, especially for developers not used to native/C++\ndebugging. However, using Visual Studio, Electron's hosted Symbol Server,\nand the Electron source code, you can enable step-through debugging\nwith breakpoints inside Electron's source code.\nSee 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.\n\nRequirements\n\n\nA debug build of Electron: The easiest way is usually building it\nyourself, using the tools and prerequisites listed in the\nbuild instructions for Windows. While you can\nattach to and debug Electron as you can download it directly, you will\nfind that it is heavily optimized, making debugging substantially more\ndifficult: The debugger will not be able to show you the content of all\nvariables and the execution path can seem strange because of inlining,\ntail calls, and other compiler optimizations.\n\n\nVisual Studio with C++ Tools: The free community editions of Visual\nStudio 2013 and Visual Studio 2015 both work. Once installed,\nconfigure Visual Studio to use Electron's Symbol server.\nIt will enable Visual Studio to gain a better understanding of what happens\ninside Electron, making it easier to present variables in a human-readable\nformat.\n\n\nProcMon: The free SysInternals tool allows you to inspect\na processes parameters, file handles, and registry operations.\n\n\n\nAttaching to and Debugging Electron\nTo start a debugging session, open up PowerShell/CMD and execute your debug\nbuild of Electron, using the application to open as a parameter.\n$ ./out/Testing/electron.exe ~/my-electron-app/\n\n\nSetting Breakpoints\nThen, open up Visual Studio. Electron is not built with Visual Studio and hence\ndoes not contain a project file - you can however open up the source code files\n\"As File\", meaning that Visual Studio will open them up by themselves. You can\nstill set breakpoints - Visual Studio will automatically figure out that the\nsource code matches the code running in the attached process and break\naccordingly.\nRelevant code files can be found in ./shell/.\n\nAttaching\nYou can attach the Visual Studio debugger to a running process on a local or\nremote computer. After the process is running, click Debug / Attach to Process\n(or press CTRL+ALT+P) to open the \"Attach to Process\" dialog box. You can use\nthis capability to debug apps that are running on a local or remote computer,\ndebug multiple processes simultaneously.\nIf Electron is running under a different user account, select the\nShow processes from all users check box. Notice that depending on how many\nBrowserWindows your app opened, you will see multiple processes. A typical\none-window app will result in Visual Studio presenting you with two\nElectron.exe entries - one for the main process and one for the renderer\nprocess. Since the list only gives you names, there's currently no reliable\nway of figuring out which is which.\n\nWhich Process Should I Attach to?\nCode executed within the main process (that is, code found in or eventually run\nby your main JavaScript file) will run inside the main process, while other\ncode will execute inside its respective renderer process.\nYou can be attached to multiple programs when you are debugging, but only one\nprogram is active in the debugger at any time. You can set the active program\nin the Debug Location toolbar or the Processes window.\n\nUsing ProcMon to Observe a Process\nWhile Visual Studio is fantastic for inspecting specific code paths, ProcMon's\nstrength is really in observing everything your application is doing with the\noperating system - it captures File, Registry, Network, Process, and Profiling\ndetails of processes. It attempts to log all events occurring and can be\nquite overwhelming, but if you seek to understand what and how your application\nis doing to the operating system, it can be a valuable resource.\nFor an introduction to ProcMon's basic and advanced debugging features, go check\nout this video tutorial provided by Microsoft.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Debugging on Windows",
"doc:debug-instructions-windows",
"tutorial:Debugging on Windows",
"tutorial:debug-instructions-windows"
]
},
{
"objectID": "tutorial-debugging-instructions-macos",
"title": "Debugging on macOS",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/development/debugging-instructions-macos.md",
"url": "https://electronjs.org/docs/development/debugging-instructions-macos",
"slug": "debugging-instructions-macos",
"body": "Debugging on macOS\nIf you experience crashes or issues in Electron that you believe are not caused\nby your JavaScript application, but instead by Electron itself, debugging can\nbe a little bit tricky, especially for developers not used to native/C++\ndebugging. However, using lldb, and the Electron source code, you can enable\nstep-through debugging with breakpoints inside Electron's source code.\nYou can also use XCode for debugging if\nyou prefer a graphical interface.\n\nRequirements\n\n\nA debug build of Electron: The easiest way is usually building it\nyourself, using the tools and prerequisites listed in the\nbuild instructions for macOS. While you can\nattach to and debug Electron as you can download it directly, you will\nfind that it is heavily optimized, making debugging substantially more\ndifficult: The debugger will not be able to show you the content of all\nvariables and the execution path can seem strange because of inlining,\ntail calls, and other compiler optimizations.\n\n\nXcode: In addition to Xcode, also install the Xcode command line tools.\nThey include LLDB, the default debugger in Xcode on macOS. It supports\ndebugging C, Objective-C and C++ on the desktop and iOS devices and simulator.\n\n\n.lldbinit: Create or edit ~/.lldbinit to allow Chromium code to be properly source-mapped.\ncommand script import ~/electron/src/tools/lldb/lldbinit.py\n\n\n\n\nAttaching to and Debugging Electron\nTo start a debugging session, open up Terminal and start lldb, passing a non-release\nbuild of Electron as a parameter.\n$ lldb ./out/Testing/Electron.app\n(lldb) target create \"./out/Testing/Electron.app\"\nCurrent executable set to './out/Testing/Electron.app' (x86_64).\n\n\nSetting Breakpoints\nLLDB is a powerful tool and supports multiple strategies for code inspection. For\nthis basic introduction, let's assume that you're calling a command from JavaScript\nthat isn't behaving correctly - so you'd like to break on that command's C++\ncounterpart inside the Electron source.\nRelevant code files can be found in ./shell/.\nLet's assume that you want to debug app.setName(), which is defined in browser.cc\nas Browser::SetName(). Set the breakpoint using the breakpoint command, specifying\nfile and line to break on:\n(lldb) breakpoint set --file browser.cc --line 117\nBreakpoint 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\n\nThen, start Electron:\n(lldb) run\n\nThe app will immediately be paused, since Electron sets the app's name on launch:\n(lldb) run\nProcess 25244 launched: '/Users/fr/Code/electron/out/Testing/Electron.app/Contents/MacOS/Electron' (x86_64)\nProcess 25244 stopped\n* 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\n frame #0: 0x0000000100162db4 Electron Framework`atom::Browser::SetName(this=0x0000000108b14f20, name=\"Electron\") + 20 at browser.cc:118\n 115 }\n 116\n 117 void Browser::SetName(const std::string& name) {\n-> 118 name_override_ = name;\n 119 }\n 120\n 121 int Browser::GetBadgeCount() {\n(lldb)\n\nTo show the arguments and local variables for the current frame, run frame variable (or fr v),\nwhich will show you that the app is currently setting the name to \"Electron\".\n(lldb) frame variable\n(atom::Browser *) this = 0x0000000108b14f20\n(const string &) name = \"Electron\": {\n [...]\n}\n\nTo do a source level single step in the currently selected thread, execute step (or s).\nThis would take you into name_override_.empty(). To proceed and do a step over,\nrun next (or n).\n(lldb) step\nProcess 25244 stopped\n* 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\n frame #0: 0x0000000100162dcc Electron Framework`atom::Browser::SetName(this=0x0000000108b14f20, name=\"Electron\") + 44 at browser.cc:119\n 116\n 117 void Browser::SetName(const std::string& name) {\n 118 name_override_ = name;\n-> 119 }\n 120\n 121 int Browser::GetBadgeCount() {\n 122 return badge_count_;\n\nNOTE: If you don't see source code when you think you should, you may not have added the ~/.lldbinit file above.\nTo finish debugging at this point, run process continue. You can also continue until a certain\nline is hit in this thread (thread until 100). This command will run the thread in the current\nframe till it reaches line 100 in this frame or stops if it leaves the current frame.\nNow, if you open up Electron's developer tools and call setName, you will once again hit the\nbreakpoint.\n\nFurther Reading\nLLDB is a powerful tool with a great documentation. To learn more about it, consider\nApple's debugging documentation, for instance the LLDB Command Structure Reference\nor the introduction to Using LLDB as a Standalone Debugger.\nYou can also check out LLDB's fantastic manual and tutorial, which\nwill explain more complex debugging scenarios.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Debugging on macOS",
"doc:debugging-instructions-macos",
"tutorial:Debugging on macOS",
"tutorial:debugging-instructions-macos"
]
},
{
"objectID": "tutorial-debugging-instructions-macos-xcode",
"title": "Debugging with XCode",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/development/debugging-instructions-macos-xcode.md",
"url": "https://electronjs.org/docs/development/debugging-instructions-macos-xcode",
"slug": "debugging-instructions-macos-xcode",
"body": "Debugging with XCode\n\nGenerate xcode project for debugging sources (cannot build code from xcode)\nRun gn gen with the --ide=xcode argument.\n$ gn gen out/Testing --ide=xcode\n\nThis will generate the electron.ninja.xcworkspace. You will have to open this workspace\nto set breakpoints and inspect.\nSee gn help gen for more information on generating IDE projects with GN.\n\nDebugging and breakpoints\nLaunch Electron app after build.\nYou can now open the xcode workspace created above and attach to the Electron process\nthrough the Debug > Attach To Process > Electron debug menu. [Note: If you want to debug\nthe renderer process, you need to attach to the Electron Helper as well.]\nYou can now set breakpoints in any of the indexed files. However, you will not be able\nto set breakpoints directly in the Chromium source.\nTo set break points in the Chromium source, you can choose Debug > Breakpoints > Create\nSymbolic Breakpoint and set any function name as the symbol. This will set the breakpoint\nfor all functions with that name, from all the classes if there are more than one.\nYou can also do this step of setting break points prior to attaching the debugger,\nhowever, actual breakpoints for symbolic breakpoint functions may not show up until the\ndebugger is attached to the app.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Debugging with XCode",
"doc:debugging-instructions-macos-xcode",
"tutorial:Debugging with XCode",
"tutorial:debugging-instructions-macos-xcode"
]
},
{
"objectID": "tutorial-debugging-main-process",
"title": "Debugging the Main Process",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/debugging-main-process.md",
"url": "https://electronjs.org/docs/tutorial/debugging-main-process",
"slug": "debugging-main-process",
"body": "Debugging the Main Process\nThe DevTools in an Electron browser window can only debug JavaScript that's\nexecuted in that window (i.e. the web pages). To debug JavaScript that's\nexecuted in the main process you will need to use an external debugger and\nlaunch Electron with the --inspect or --inspect-brk switch.\n\nCommand Line Switches\nUse one of the following command line switches to enable debugging of the main\nprocess:\n\n--inspect=[port]\nElectron will listen for V8 inspector protocol messages on the specified port,\nan external debugger will need to connect on this port. The default port is\n5858.\nelectron --inspect=5858 your/app\n\n\n--inspect-brk=[port]\nLike --inspect but pauses execution on the first line of JavaScript.\n\nExternal Debuggers\nYou will need to use a debugger that supports the V8 inspector protocol.\n\nConnect Chrome by visiting chrome://inspect and selecting to inspect the\nlaunched Electron app present there.\nDebugging in VSCode\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Debugging the Main Process",
"doc:debugging-main-process",
"tutorial:Debugging the Main Process",
"tutorial:debugging-main-process"
]
},
{
"objectID": "tutorial-debugging-vscode",
"title": "Debugging in VSCode",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/debugging-vscode.md",
"url": "https://electronjs.org/docs/tutorial/debugging-vscode",
"slug": "debugging-vscode",
"body": "Debugging in VSCode\nThis guide goes over how to set up VSCode debugging for both your own Electron project as well as the native Electron codebase.\n\nDebugging your Electron app\n\nMain process\n\n1. Open an Electron project in VSCode.\n$ git clone git@github.com:electron/electron-quick-start.git\n$ code electron-quick-start\n\n\n2. Add a file .vscode/launch.json with the following configuration:\n{\n \"version\": \"0.2.0\",\n \"configurations\": [\n {\n \"name\": \"Debug Main Process\",\n \"type\": \"node\",\n \"request\": \"launch\",\n \"cwd\": \"${workspaceFolder}\",\n \"runtimeExecutable\": \"${workspaceFolder}/node_modules/.bin/electron\",\n \"windows\": {\n \"runtimeExecutable\": \"${workspaceFolder}/node_modules/.bin/electron.cmd\"\n },\n \"args\" : [\".\"],\n \"outputCapture\": \"std\"\n }\n ]\n}\n\n\n3. Debugging\nSet some breakpoints in main.js, and start debugging in the Debug View. You should be able to hit the breakpoints.\nHere 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\n\nDebugging the Electron codebase\nIf you want to build Electron from source and modify the native Electron codebase, this section will help you in testing your modifications.\nFor 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.\n\nWindows (C++)\n\n1. Open an Electron project in VSCode.\n$ git clone git@github.com:electron/electron-quick-start.git\n$ code electron-quick-start\n\n\n2. Add a file .vscode/launch.json with the following configuration:\n{\n \"version\": \"0.2.0\",\n \"configurations\": [\n {\n \"name\": \"(Windows) Launch\",\n \"type\": \"cppvsdbg\",\n \"request\": \"launch\",\n \"program\": \"${workspaceFolder}\\\\out\\\\your-executable-location\\\\electron.exe\",\n \"args\": [\"your-electron-project-path\"],\n \"stopAtEntry\": false,\n \"cwd\": \"${workspaceFolder}\",\n \"environment\": [\n {\"name\": \"ELECTRON_ENABLE_LOGGING\", \"value\": \"true\"},\n {\"name\": \"ELECTRON_ENABLE_STACK_DUMPING\", \"value\": \"true\"},\n {\"name\": \"ELECTRON_RUN_AS_NODE\", \"value\": \"\"},\n ],\n \"externalConsole\": false,\n \"sourceFileMap\": {\n \"o:\\\\\": \"${workspaceFolder}\",\n },\n },\n ]\n}\n\nConfiguration Notes\n\ncppvsdbg requires the built-in C/C++ extension be enabled.\n${workspaceFolder} is the full path to Chromium's src directory.\nyour-executable-location will be one of the following depending on a few items:\nTesting: If you are using the default settings of Electron's Build-Tools or the default instructions when building from source.\nRelease: If you built a Release build rather than a Testing build.\nyour-directory-name: If you modified this during your build process from the default, this will be whatever you specified.\n\nThe 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.\n\n\n3. Debugging\nSet some breakpoints in the .cc files of your choosing in the native Electron C++ code, and start debugging in the Debug View.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Debugging in VSCode",
"doc:debugging-vscode",
"tutorial:Debugging in VSCode",
"tutorial:debugging-vscode"
]
},
{
"objectID": "tutorial-desktop-environment-integration",
"title": "Desktop Environment Integration",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/desktop-environment-integration.md",
"url": "https://electronjs.org/docs/tutorial/desktop-environment-integration",
"slug": "desktop-environment-integration",
"body": "Desktop Environment Integration\nDifferent operating systems provide different features for integrating desktop\napplications into their desktop environments. For example, on Windows,\napplications can put shortcuts in the JumpList of task bar, and on Mac,\napplications can put a custom menu in the dock menu.\nThis guide explains how to integrate your application into those desktop\nenvironments with Electron APIs.\n\nNotifications\nSee the Notifications documentation.\n\nRecent Documents\nSee Recent Documents documentation.\n\nProgress Bar\nSee the Progress Bar documentation.\n\nUnity Launcher\nSee the Unity Launcher documentation.\n\nRepresented File for macOS Window\nSee the Represented File documentation.\n\nDragging files out of the window\nSee the Native File Drag & Drop documentation.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Desktop Environment Integration",
"doc:desktop-environment-integration",
"tutorial:Desktop Environment Integration",
"tutorial:desktop-environment-integration"
]
},
{
"objectID": "tutorial-devtools-extension",
"title": "DevTools Extension",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/devtools-extension.md",
"url": "https://electronjs.org/docs/tutorial/devtools-extension",
"slug": "devtools-extension",
"body": "DevTools Extension\nElectron supports Chrome DevTools extensions, which can\nbe used to extend the ability of Chrome's developer tools for debugging\npopular web frameworks.\n\nLoading a DevTools extension with tooling\nThe easiest way to load a DevTools extension is to use third-party tooling to automate the\nprocess for you. electron-devtools-installer is a popular\nNPM package that does just that.\n\nManually loading a DevTools extension\nIf you don't want to use the tooling approach, you can also do all of the necessary\noperations by hand. To load an extension in Electron, you need to download it via Chrome,\nlocate its filesystem path, and then load it into your Session by calling the\n[ses.loadExtension] API.\nUsing the React Developer Tools as an example:\n\n\nInstall the extension in Google Chrome.\n\n\nNavigate to chrome://extensions, and find its extension ID, which is a hash\nstring like fmkadmapgofadopljbjfkapdkoienihi.\n\n\nFind out the filesystem location used by Chrome for storing extensions:\n\non Windows it is %LOCALAPPDATA%\\Google\\Chrome\\User Data\\Default\\Extensions;\non Linux it could be:\n~/.config/google-chrome/Default/Extensions/\n~/.config/google-chrome-beta/Default/Extensions/\n~/.config/google-chrome-canary/Default/Extensions/\n~/.config/chromium/Default/Extensions/\n\non macOS it is ~/Library/Application Support/Google/Chrome/Default/Extensions.\n\n\n\nPass the location of the extension to the ses.loadExtension\nAPI. For React Developer Tools v4.9.0, it looks something like:\n const { app, session } = require('electron')\n const path = require('path')\n const os = require('os')\n\n // on macOS\n const reactDevToolsPath = path.join(\n os.homedir(),\n '/Library/Application Support/Google/Chrome/Default/Extensions/fmkadmapgofadopljbjfkapdkoienihi/4.9.0_0'\n )\n\n app.whenReady().then(async () => {\n await session.defaultSession.loadExtension(reactDevToolsPath)\n })\n\n\n\nNotes:\n\nloadExtension returns a Promise with an Extension object,\nwhich contains metadata about the extension that was loaded. This promise needs to\nresolve (e.g. with an await expression) before loading a page. Otherwise, the\nextension won't be guaranteed to load.\nloadExtension cannot be called before the ready event of the app module\nis emitted, nor can it be called on in-memory (non-persistent) sessions.\nloadExtension must be called on every boot of your app if you want the\nextension to be loaded.\n\n\nRemoving a DevTools extension\nYou can pass the extension's ID to the ses.removeExtension API to\nremove it from your Session. Loaded extensions are not persisted between\napp launches.\n\nDevTools extension support\nElectron only supports\na limited set of chrome.* APIs,\nso extensions using unsupported chrome.* APIs under the hood may not work.\nThe following Devtools extensions have been tested to work in Electron:\n\nEmber Inspector\nReact Developer Tools\nBackbone Debugger\njQuery Debugger\nAngularJS Batarang\nVue.js devtools\nCerebral Debugger\nRedux DevTools Extension\nMobX Developer Tools\n\n\nWhat should I do if a DevTools extension is not working?\nFirst, please make sure the extension is still being maintained and is compatible\nwith the latest version of Google Chrome. We cannot provide additional support for\nunsupported extensions.\nIf the extension works on Chrome but not on Electron, file a bug in Electron's\nissue tracker and describe which part\nof the extension is not working as expected.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:DevTools Extension",
"doc:devtools-extension",
"tutorial:DevTools Extension",
"tutorial:devtools-extension"
]
},
{
"objectID": "tutorial-electron-timelines",
"title": "Electron Release Timelines",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/electron-timelines.md",
"url": "https://electronjs.org/docs/tutorial/electron-timelines",
"slug": "electron-timelines",
"body": "Electron Release Timelines\n\nThe -beta.1 and stable dates are our solid release dates.\nWe strive for weekly beta releases, however we often release more betas than scheduled.\nAll dates are our goals but there may be reasons for adjusting the stable deadline, such as security bugs.\nTake a look at the 5.0.0 Timeline blog post for info about publicizing our release dates.\nSince Electron 6.0, we've been targeting every other Chromium version and releasing our stable on the same day as Chrome stable. You can reference Chromium's release schedule here. See Electron's new release cadence blog post for more details on our release schedule.\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nVersion-beta.1StableChromeNode2.0.02018-02-212018-05-01M61v8.93.0.02018-06-212018-09-18M66v10.24.0.02018-10-112018-12-20M69v10.115.0.02019-01-222019-04-24M73v12.06.0.02019-05-012019-07-30M76v12.47.0.02019-08-012019-10-22M78v12.88.0.02019-10-242020-02-04M80v12.139.0.02020-02-062020-05-19M83v12.1410.0.02020-05-212020-08-25M85v12.1611.0.02020-08-272020-11-17M87v12.1812.0.02020-11-192021-03-02M89v14.1613.0.02021-03-042021-05-25M91v14.x",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Electron Release Timelines",
"doc:electron-timelines",
"tutorial:Electron Release Timelines",
"tutorial:electron-timelines"
]
},
{
"objectID": "tutorial-electron-versioning",
"title": "Electron Versioning",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/electron-versioning.md",
"url": "https://electronjs.org/docs/tutorial/electron-versioning",
"slug": "electron-versioning",
"body": "Electron Versioning\n\nA detailed look at our versioning policy and implementation.\n\nAs of version 2.0.0, Electron follows SemVer. The following command will install the most recent stable build of Electron:\nnpm install --save-dev electron\n\nTo update an existing project to use the latest stable version:\nnpm install --save-dev electron@latest\n\n\nVersion 1.x\nElectron 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.\nHere is an example of the 1.x strategy:\n\nAn 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.\n\nVersion 2.0 and Beyond\nThere 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.\n\nStrict use of SemVer\nIntroduction of semver-compliant -beta tags\nIntroduction of conventional commit messages\nWell-defined stabilization branches\nThe master branch is versionless; only stabilization branches contain version information\n\nWe will cover in detail how git branching works, how npm tagging works, what developers should expect to see, and how one can backport changes.\n\nSemVer\nFrom 2.0 onward, Electron will follow SemVer.\nBelow is a table explicitly mapping types of changes to their corresponding category of SemVer (e.g. Major, Minor, Patch).\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nMajor Version IncrementsMinor Version IncrementsPatch Version IncrementsElectron breaking API changesElectron non-breaking API changesElectron bug fixesNode.js major version updatesNode.js minor version updatesNode.js patch version updatesChromium version updatesfix-related chromium patches\nNote that most Chromium updates will be considered breaking. Fixes that can be backported will likely be cherry-picked as patches.\n\nStabilization Branches\nStabilization 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.\n\nSince 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\nWe 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.\n\nOlder 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.\n\nBeta Releases and Bug Fixes\nDevelopers 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 youre 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 :\n\nUse ~2.0.0 to admit only stability or security related fixes to your 2.0.0 release.\nUse ^2.0.0 to admit non-breaking reasonably stable feature work as well as security and bug fixes.\n\nWhats 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.\nWhatever you choose, you will periodically have to bump the version in your package.json as breaking changes are a fact of Chromium life.\nThe process is as follows:\n\nAll new major and minor releases lines begin with a beta series indicated by SemVer prerelease tags of beta.N, e.g. 2.0.0-beta.1. After the first beta, subsequent beta releases must meet all of the following conditions:\nThe change is backwards API-compatible (deprecations are allowed)\nThe risk to meeting our stability timeline must be low.\n\nIf allowed changes need to be made once a release is beta, they are applied and the prerelease tag is incremented, e.g. 2.0.0-beta.2.\nIf a particular beta release is generally regarded as stable, it will be re-released as a stable build, changing only the version information. e.g. 2.0.0. After the first stable, all changes must be backwards-compatible bug or security fixes.\nIf future bug fixes or security patches need to be made once a release is stable, they are applied and the patch version is incremented\ne.g. 2.0.1.\n\nSpecifically, the above means:\n\nAdmitting non-breaking-API changes before Week 3 in the beta cycle is okay, even if those changes have the potential to cause moderate side-effects.\nAdmitting feature-flagged changes, that do not otherwise alter existing code paths, at most points in the beta cycle is okay. Users can explicitly enable those flags in their apps.\nAdmitting features of any sort after Week 3 in the beta cycle is 👎 without a very good reason.\n\nFor each major and minor bump, you should expect to see something like the following:\n2.0.0-beta.1\n2.0.0-beta.2\n2.0.0-beta.3\n2.0.0\n2.0.1\n2.0.2\n\nAn example lifecycle in pictures:\n\nA new release branch is created that includes the latest set of features. It is published as 2.0.0-beta.1.\n\nA bug fix comes into master that can be backported to the release branch. The patch is applied, and a new beta is published as 2.0.0-beta.2.\n\nThe beta is considered generally stable and it is published again as a non-beta under 2.0.0.\n\nLater, a zero-day exploit is revealed and a fix is applied to master. We backport the fix to the 2-0-x line and release 2.0.1.\n\n\nA few examples of how various SemVer ranges will pick up new releases:\n\n\nMissing Features: Alphas\nOur 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.\nAs a future consideration, we may introduce one or both of the following:\n\nalpha releases that have looser stability constraints to betas; for example it would be allowable to admit new features while a stability channel is in alpha\n\n\nFeature Flags\nFeature 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:\n\nit is enabled/disabled either at runtime, or build-time; we do not support the concept of a request-scoped feature flag\nit completely segments new and old code paths; refactoring old code to support a new feature violates the feature-flag contract\nfeature flags are eventually removed after the feature is released\n\n\nSemantic Commits\nWe 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:\n\n\nCommits that would result in a SemVer major bump must start their body with BREAKING CHANGE:.\n\n\nCommits that would result in a SemVer minor bump must start with feat:.\n\n\nCommits that would result in a SemVer patch bump must start with fix:.\n\n\nWe allow squashing of commits, provided that the squashed message adheres to the above message format.\n\n\nIt 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.\n\n\n\nVersioned master\n\nThe master branch will always contain the next major version X.0.0-nightly.DATE in its package.json\nRelease branches are never merged back to master\nRelease branches do contain the correct version in their package.json\nAs soon as a release branch is cut for a major, master must be bumped to the next major. I.e. master is always versioned as the next theoretical release branch\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Electron Versioning",
"doc:electron-versioning",
"tutorial:Electron Versioning",
"tutorial:electron-versioning"
]
},
{
"objectID": "tutorial-electron-vs-nwjs",
"title": "Technical Differences Between Electron and NW.js",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/development/electron-vs-nwjs.md",
"url": "https://electronjs.org/docs/development/electron-vs-nwjs",
"slug": "electron-vs-nwjs",
"body": "Technical Differences Between Electron and NW.js\nLike NW.js, Electron provides a platform to write desktop applications with web\ntechnologies. Both platforms enable developers to utilize HTML, JavaScript, and\nNode.js. On the surface, they seem very similar.\nThere are however fundamental differences between the two projects that make\nElectron a completely separate product from NW.js.\n\n1) Entry of Application\nIn NW.js, the main entry point of an application can be an HTML web page. In\nthat case, NW.js will open the given entry point in a browser window.\nIn Electron, the entry point is always a JavaScript script. Instead of providing a\nURL directly, you manually create a browser window and load an HTML file using\nthe API. You also need to listen to window events to decide when to quit the\napplication.\nElectron works more like the Node.js runtime. Electron's APIs are lower level so\nyou can use it for browser testing in place of\nPhantomJS.\n\n2) Node Integration\nIn NW.js, the Node integration in web pages requires patching Chromium to work,\nwhile in Electron we chose a different way to integrate the libuv loop with\neach platform's message loop to avoid hacking Chromium. See the\nnode_bindings code for how that was done.\n\n3) JavaScript Contexts\nIf you are an experienced NW.js user, you should be familiar with the concept of\nNode context and web context. These concepts were invented because of how NW.js\nwas implemented.\nBy using the\nmulti-context\nfeature of Node, Electron doesn't introduce a new JavaScript context in web\npages.\nNote: NW.js has optionally supported multi-context since 0.13.\n\n4) Legacy Support\nNW.js still offers a \"legacy release\" that supports Windows XP. It doesn't\nreceive security updates.\nGiven that hardware manufacturers, Microsoft, Chromium, and Node.js haven't\nreleased even critical security updates for that system, we have to warn you\nthat using Windows XP is wildly insecure and outright irresponsible.\nHowever, we understand that requirements outside our wildest imagination may\nexist, so if you're looking for something like Electron that runs on Windows XP,\nthe NW.js legacy release might be the right fit for you.\n\n5) Features\nThere are numerous differences in the amount of supported features. Electron has\na bigger community, more production apps using it, and a large amount of\nuserland modules available on npm.\nAs an example, Electron has built-in support for automatic updates and countless\ntools that make the creation of installers easier. As an example in favor of\nNW.js, NW.js supports more Chrome.* APIs for the development of Chrome Apps.\nNaturally, we believe that Electron is the better platform for polished\nproduction applications built with web technologies (like Visual Studio Code,\nSlack, or Facebook Messenger); however, we want to be fair to our web technology\nfriends. If you have feature needs that Electron does not meet, you might want\nto try NW.js.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Technical Differences Between Electron and NW.js",
"doc:electron-vs-nwjs",
"tutorial:Technical Differences Between Electron and NW.js",
"tutorial:electron-vs-nwjs"
]
},
{
"objectID": "tutorial-experimental",
"title": "Experimental APIs",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/experimental.md",
"url": "https://electronjs.org/docs/experimental",
"slug": "experimental",
"body": "Experimental APIs\nSome of Electrons APIs are tagged with _Experimental_ in the documentation.\nThis tag indicates that the API may not be considered stable and the API may\nbe removed or modified more frequently than other APIs with less warning.\n\nConditions for an API to be tagged as Experimental\nAnyone can request an API be tagged as experimental in a feature PR, disagreements\non the experimental nature of a feature can be discussed in the API WG if they\ncan't be resolved in the PR.\n\nProcess for removing the Experimental tag\nOnce an API has been stable and in at least two major stable release lines it\ncan be nominated to have its experimental tag removed. This discussion should\nhappen at an API WG meeting. Things to consider when discussing / nominating:\n\nThe above \"two major stables release lines\" condition must have been met\nDuring that time no major bugs / issues should have been caused by the adoption of this feature\nThe API is stable enough and hasn't been heavily impacted by Chromium upgrades\nIs anyone using the API?\nIs the API fulfilling the original proposed usecases, does it have any gaps?\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Experimental APIs",
"doc:experimental",
"tutorial:Experimental APIs",
"tutorial:experimental"
]
},
{
"objectID": "tutorial-faq",
"title": "Electron FAQ",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/faq.md",
"url": "https://electronjs.org/docs/faq",
"slug": "faq",
"body": "Electron FAQ\n\nWhy am I having trouble installing Electron?\nWhen running npm install electron, some users occasionally encounter\ninstallation errors.\nIn almost all cases, these errors are the result of network problems and not\nactual issues with the electron npm package. Errors like ELIFECYCLE,\nEAI_AGAIN, ECONNRESET, and ETIMEDOUT are all indications of such\nnetwork problems. The best resolution is to try switching networks, or\nwait a bit and try installing again.\nYou can also attempt to download Electron directly from\nelectron/electron/releases\nif installing via npm is failing.\n\nWhen will Electron upgrade to latest Chrome?\nThe Chrome version of Electron is usually bumped within one or two weeks after\na new stable Chrome version gets released. This estimate is not guaranteed and\ndepends on the amount of work involved with upgrading.\nOnly the stable channel of Chrome is used. If an important fix is in beta or dev\nchannel, we will back-port it.\nFor more information, please see the security introduction.\n\nWhen will Electron upgrade to latest Node.js?\nWhen a new version of Node.js gets released, we usually wait for about a month\nbefore upgrading the one in Electron. So we can avoid getting affected by bugs\nintroduced in new Node.js versions, which happens very often.\nNew features of Node.js are usually brought by V8 upgrades, since Electron is\nusing the V8 shipped by Chrome browser, the shiny new JavaScript feature of a\nnew Node.js version is usually already in Electron.\n\nHow to share data between web pages?\nTo share data between web pages (the renderer processes) the simplest way is to\nuse HTML5 APIs which are already available in browsers. Good candidates are\nStorage API, localStorage,\nsessionStorage, and IndexedDB.\nAlternatively, you can use the IPC primitives that are provided by Electron. To\nshare data between the main and renderer processes, you can use the\nipcMain and ipcRenderer modules.\nTo communicate directly between web pages, you can send a\nMessagePort from one to the other, possibly via the main process\nusing ipcRenderer.postMessage().\nSubsequent communication over message ports is direct and does not detour through\nthe main process.\n\nMy app's tray disappeared after a few minutes.\nThis happens when the variable which is used to store the tray gets\ngarbage collected.\nIf you encounter this problem, the following articles may prove helpful:\n\nMemory Management\nVariable Scope\n\nIf you want a quick fix, you can make the variables global by changing your\ncode from this:\nconst { app, Tray } = require('electron')\napp.whenReady().then(() => {\n const tray = new Tray('/path/to/icon.png')\n tray.setTitle('hello world')\n})\n\nto this:\nconst { app, Tray } = require('electron')\nlet tray = null\napp.whenReady().then(() => {\n tray = new Tray('/path/to/icon.png')\n tray.setTitle('hello world')\n})\n\n\nI can not use jQuery/RequireJS/Meteor/AngularJS in Electron.\nDue to the Node.js integration of Electron, there are some extra symbols\ninserted into the DOM like module, exports, require. This causes problems\nfor some libraries since they want to insert the symbols with the same names.\nTo solve this, you can turn off node integration in Electron:\n// In the main process.\nconst { BrowserWindow } = require('electron')\nconst win = new BrowserWindow({\n webPreferences: {\n nodeIntegration: false\n }\n})\nwin.show()\n\nBut if you want to keep the abilities of using Node.js and Electron APIs, you\nhave to rename the symbols in the page before including other libraries:\n<head>\n<script>\nwindow.nodeRequire = require;\ndelete window.require;\ndelete window.exports;\ndelete window.module;\n</script>\n<script type=\"text/javascript\" src=\"jquery.js\"></script>\n</head>\n\n\nrequire('electron').xxx is undefined.\nWhen using Electron's built-in module you might encounter an error like this:\n> require('electron').webFrame.setZoomFactor(1.0)\nUncaught TypeError: Cannot read property 'setZoomLevel' of undefined\n\nIt is very likely you are using the module in the wrong process. For example\nelectron.app can only be used in the main process, while electron.webFrame\nis only available in renderer processes.\n\nThe font looks blurry, what is this and what can I do?\nIf sub-pixel anti-aliasing is deactivated, then fonts on LCD screens can look blurry. Example:\n\nSub-pixel anti-aliasing needs a non-transparent background of the layer containing the font glyphs. (See this issue for more info).\nTo achieve this goal, set the background in the constructor for BrowserWindow:\nconst { BrowserWindow } = require('electron')\nconst win = new BrowserWindow({\n backgroundColor: '#fff'\n})\n\nThe 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.\nNotice that just setting the background in the CSS does not have the desired effect.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Electron FAQ",
"doc:faq",
"tutorial:Electron FAQ",
"tutorial:faq"
]
},
{
"objectID": "tutorial-fuses",
"title": "Electron Fuses",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/fuses.md",
"url": "https://electronjs.org/docs/tutorial/fuses",
"slug": "fuses",
"body": "Electron Fuses\n\nPackage time feature toggles\n\n\nWhat are fuses?\nFor 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.\nFuses 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).\n\nHow do I flip the fuses?\n\nThe easy way\nWe'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.\nrequire('@electron/fuses').flipFuses(\n // Path to electron\n require('electron'),\n // Fuses to flip\n {\n runAsNode: false\n }\n)\n\n\nThe hard way\n\nQuick Glossary\n\nFuse Wire: A sequence of bytes in the Electron binary used to control the fuses\nSentinel: A static known sequence of bytes you can use to locate the fuse wire\nFuse Schema: The format / allowed values for the fuse wire\n\nManually 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.\nSomewhere in the Electron binary there will be a sequence of bytes that look like this:\n| ...binary | sentinel_bytes | fuse_version | fuse_wire_length | fuse_wire | ...binary |\n\n\nsentinel_bytes is always this exact string dL7pKGdnNz796PbbjQWNKmHXBZaB9tsX\nfuse_version is a single byte whose unsigned integer value represents the version of the fuse schema\nfuse_wire_length is a single byte whose unsigned integer value represents the number of fuses in the following fuse wire\nfuse_wire is a sequence of N bytes, each byte represents a single fuse and its state.\n\"0\" (0x30) indicates the fuse is disabled\n\"1\" (0x31) indicates the fuse is enabled\n\"r\" (0x72) indicates the fuse has been removed and changing the byte to either 1 or 0 will have no effect.\n\n\nTo 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.\nYou can view the current schema here.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Electron Fuses",
"doc:fuses",
"tutorial:Electron Fuses",
"tutorial:fuses"
]
},
{
"objectID": "tutorial-glossary",
"title": "Glossary",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/glossary.md",
"url": "https://electronjs.org/docs/glossary",
"slug": "glossary",
"body": "Glossary\nThis page defines some terminology that is commonly used in Electron development.\n\nASAR\nASAR stands for Atom Shell Archive Format. An asar archive is a simple\ntar-like format that concatenates files into a single file. Electron can read\narbitrary files from it without unpacking the whole file.\nThe ASAR format was created primarily to improve performance on Windows... TODO\n\nCRT\nThe C Run-time Library (CRT) is the part of the C++ Standard Library that\nincorporates the ISO C99 standard library. The Visual C++ libraries that\nimplement the CRT support native code development, and both mixed native and\nmanaged code, and pure managed code for .NET development.\n\nDMG\nAn Apple Disk Image is a packaging format used by macOS. DMG files are\ncommonly used for distributing application \"installers\". electron-builder\nsupports dmg as a build target.\n\nIME\nInput Method Editor. A program that allows users to enter characters and\nsymbols not found on their keyboard. For example, this allows users of Latin\nkeyboards to input Chinese, Japanese, Korean and Indic characters.\n\nIDL\nInterface description language. Write function signatures and data types in a format that can be used to generate interfaces in Java, C++, JavaScript, etc.\n\nIPC\nIPC stands for Inter-Process Communication. Electron uses IPC to send\nserialized JSON messages between the main and renderer processes.\n\nlibchromiumcontent\nA shared library that includes the Chromium Content module and all its\ndependencies (e.g., Blink, V8, etc.). Also referred to as \"libcc\".\n\ngithub.com/electron/libchromiumcontent\n\n\nmain process\nThe main process, commonly a file named main.js, is the entry point to every\nElectron app. It controls the life of the app, from open to close. It also\nmanages native elements such as the Menu, Menu Bar, Dock, Tray, etc. The\nmain process is responsible for creating each new renderer process in the app.\nThe full Node API is built in.\nEvery app's main process file is specified in the main property in\npackage.json. This is how electron . knows what file to execute at startup.\nIn Chromium, this process is referred to as the \"browser process\". It is\nrenamed in Electron to avoid confusion with renderer processes.\nSee also: process, renderer process\n\nMAS\nAcronym for Apple's Mac App Store. For details on submitting your app to the\nMAS, see the Mac App Store Submission Guide.\n\nMojo\nAn 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.\nSee https://chromium.googlesource.com/chromium/src/+/master/mojo/README.md\n\nnative modules\nNative modules (also called addons in\nNode.js) are modules written in C or C++ that can be loaded into Node.js or\nElectron using the require() function, and used as if they were an\nordinary Node.js module. They are used primarily to provide an interface\nbetween JavaScript running in Node.js and C/C++ libraries.\nNative Node modules are supported by Electron, but since Electron is very\nlikely to use a different V8 version from the Node binary installed in your\nsystem, you have to manually specify the location of Electrons headers when\nbuilding native modules.\nSee also Using Native Node Modules.\n\nNSIS\nNullsoft Scriptable Install System is a script-driven Installer\nauthoring tool for Microsoft Windows. It is released under a combination of\nfree software licenses, and is a widely-used alternative to commercial\nproprietary products like InstallShield. electron-builder supports NSIS\nas a build target.\n\nOSR\nOSR (Off-screen rendering) can be used for loading heavy page in\nbackground and then displaying it after (it will be much faster).\nIt allows you to render page without showing it on screen.\n\nprocess\nA process is an instance of a computer program that is being executed. Electron\napps that make use of the main and one or many renderer process are\nactually running several programs simultaneously.\nIn Node.js and Electron, each running process has a process object. This\nobject is a global that provides information about, and control over, the\ncurrent process. As a global, it is always available to applications without\nusing require().\nSee also: main process, renderer process\n\nrenderer process\nThe renderer process is a browser window in your app. Unlike the main process,\nthere can be multiple of these and each is run in a separate process.\nThey can also be hidden.\nIn normal browsers, web pages usually run in a sandboxed environment and are not\nallowed access to native resources. Electron users, however, have the power to\nuse Node.js APIs in web pages allowing lower level operating system\ninteractions.\nSee also: process, main process\n\nSquirrel\nSquirrel is an open-source framework that enables Electron apps to update\nautomatically as new versions are released. See the autoUpdater API for\ninfo about getting started with Squirrel.\n\nuserland\nThis term originated in the Unix community, where \"userland\" or \"userspace\"\nreferred to programs that run outside of the operating system kernel. More\nrecently, the term has been popularized in the Node and npm community to\ndistinguish between the features available in \"Node core\" versus packages\npublished to the npm registry by the much larger \"user\" community.\nLike Node, Electron is focused on having a small set of APIs that provide\nall the necessary primitives for developing multi-platform desktop applications.\nThis design philosophy allows Electron to remain a flexible tool without being\noverly prescriptive about how it should be used. Userland enables users to\ncreate and share tools that provide additional functionality on top of what is\navailable in \"core\".\n\nV8\nV8 is Google's open source JavaScript engine. It is written in C++ and is\nused in Google Chrome. V8 can run standalone, or can be embedded into any C++ application.\nElectron builds V8 as part of Chromium and then points Node to that V8 when\nbuilding it.\nV8's version numbers always correspond to those of Google Chrome. Chrome 59\nincludes V8 5.9, Chrome 58 includes V8 5.8, etc.\n\nv8.dev\nnodejs.org/api/v8.html\ndocs/development/v8-development.md\n\n\nwebview\nwebview tags are used to embed 'guest' content (such as external web pages) in\nyour Electron app. They are similar to iframes, but differ in that each\nwebview runs in a separate process. It doesn't have the same\npermissions as your web page and all interactions between your app and\nembedded content will be asynchronous. This keeps your app safe from the\nembedded content.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Glossary",
"doc:glossary",
"tutorial:Glossary",
"tutorial:glossary"
]
},
{
"objectID": "tutorial-goma",
"title": "Goma",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/development/goma.md",
"url": "https://electronjs.org/docs/development/goma",
"slug": "goma",
"body": "Goma\n\nGoma is a distributed compiler service for open-source projects such as\nChromium and Android.\n\nElectron has a deployment of a custom Goma Backend that we make available to\nall Electron Maintainers. See the Access section below for details\non authentication. There is also a cache-only Goma endpoint that will be\nused by default if you do not have credentials. Requests to the cache-only\nGoma will not hit our cluster, but will read from our cache and should result\nin significantly faster build times.\n\nEnabling Goma\nCurrently the only supported way to use Goma is to use our Build Tools.\nGoma configuration is automatically included when you set up build-tools.\nIf you are a maintainer and have access to our cluster, please ensure that you run\ne init with --goma=cluster in order to configure build-tools to use\nthe Goma cluster. If you have an existing config, you can just set \"goma\": \"cluster\"\nin your config file.\n\nBuilding with Goma\nWhen you are using Goma you can run ninja with a substantially higher j\nvalue than would normally be supported by your machine.\nPlease do not set a value higher than 200 on Windows or Linux and\n50 on macOS. We monitor Goma system usage, and users found to be abusing\nit with unreasonable concurrency will be de-activated.\nninja -C out/Testing electron -j 200\n\nIf you're using build-tools, appropriate -j values will automatically\nbe used for you.\n\nMonitoring Goma\nIf you access http://localhost:8088 on your local\nmachine you can monitor compile jobs as they flow through the goma system.\n\nAccess\nFor security and cost reasons, access to Electron's Goma cluster is currently restricted\nto Electron Maintainers. If you want access please head to #access-requests in\nSlack and ping @goma-squad to ask for access. Please be aware that being a\nmaintainer does not automatically grant access and access is determined on a\ncase by case basis.\n\nUptime / Support\nWe have automated monitoring of our Goma cluster and cache at https://status.notgoma.com\nWe do not provide support for usage of Goma and any issues raised asking for help / having\nissues will probably be closed without much reason, we do not have the capacity to handle\nthat kind of support.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Goma",
"doc:goma",
"tutorial:Goma",
"tutorial:goma"
]
},
{
"objectID": "tutorial-in-app-purchases",
"title": "In-App Purchase (macOS)",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/in-app-purchases.md",
"url": "https://electronjs.org/docs/tutorial/in-app-purchases",
"slug": "in-app-purchases",
"body": "In-App Purchase (macOS)\n\nPreparing\n\nPaid Applications Agreement\nIf you haven't already, youll need to sign the Paid Applications Agreement and set up your banking and tax information in iTunes Connect.\niTunes Connect Developer Help: Agreements, tax, and banking overview\n\nCreate Your In-App Purchases\nThen, 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.\niTunes Connect Developer Help: Create an in-app purchase\n\nChange the CFBundleIdentifier\nTo 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.\n<key>CFBundleIdentifier</key>\n<string>com.example.app</string>\n\n\nCode example\nHere 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.\n// Main process\nconst { inAppPurchase } = require('electron')\nconst PRODUCT_IDS = ['id1', 'id2']\n\n// Listen for transactions as soon as possible.\ninAppPurchase.on('transactions-updated', (event, transactions) => {\n if (!Array.isArray(transactions)) {\n return\n }\n\n // Check each transaction.\n transactions.forEach(function (transaction) {\n const payment = transaction.payment\n\n switch (transaction.transactionState) {\n case 'purchasing':\n console.log(`Purchasing ${payment.productIdentifier}...`)\n break\n\n case 'purchased': {\n console.log(`${payment.productIdentifier} purchased.`)\n\n // Get the receipt url.\n const receiptURL = inAppPurchase.getReceiptURL()\n\n console.log(`Receipt URL: ${receiptURL}`)\n\n // Submit the receipt file to the server and check if it is valid.\n // @see https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html\n // ...\n // If the receipt is valid, the product is purchased\n // ...\n\n // Finish the transaction.\n inAppPurchase.finishTransactionByDate(transaction.transactionDate)\n\n break\n }\n\n case 'failed':\n\n console.log(`Failed to purchase ${payment.productIdentifier}.`)\n\n // Finish the transaction.\n inAppPurchase.finishTransactionByDate(transaction.transactionDate)\n\n break\n case 'restored':\n\n console.log(`The purchase of ${payment.productIdentifier} has been restored.`)\n\n break\n case 'deferred':\n\n console.log(`The purchase of ${payment.productIdentifier} has been deferred.`)\n\n break\n default:\n break\n }\n })\n})\n\n// Check if the user is allowed to make in-app purchase.\nif (!inAppPurchase.canMakePayments()) {\n console.log('The user is not allowed to make in-app purchase.')\n}\n\n// Retrieve and display the product descriptions.\ninAppPurchase.getProducts(PRODUCT_IDS).then(products => {\n // Check the parameters.\n if (!Array.isArray(products) || products.length <= 0) {\n console.log('Unable to retrieve the product informations.')\n return\n }\n\n // Display the name and price of each product.\n products.forEach(product => {\n console.log(`The price of ${product.localizedTitle} is ${product.formattedPrice}.`)\n })\n\n // Ask the user which product he/she wants to purchase.\n const selectedProduct = products[0]\n const selectedQuantity = 1\n\n // Purchase the selected product.\n inAppPurchase.purchaseProduct(selectedProduct.productIdentifier, selectedQuantity).then(isProductValid => {\n if (!isProductValid) {\n console.log('The product is not valid.')\n return\n }\n\n console.log('The payment has been added to the payment queue.')\n })\n})\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:In-App Purchase (macOS)",
"doc:in-app-purchases",
"tutorial:In-App Purchase (macOS)",
"tutorial:in-app-purchases"
]
},
{
"objectID": "tutorial-installation",
"title": "Installation",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/installation.md",
"url": "https://electronjs.org/docs/tutorial/installation",
"slug": "installation",
"body": "Installation\nTo install prebuilt Electron binaries, use npm.\nThe preferred method is to install Electron as a development dependency in your\napp:\nnpm install electron --save-dev\n\nSee the Electron versioning doc for info on how to\nmanage Electron versions in your apps.\n\nGlobal Installation\nYou can also install the electron command globally in your $PATH:\nnpm install electron -g\n\n\nCustomization\nIf you want to change the architecture that is downloaded (e.g., ia32 on an\nx64 machine), you can use the --arch flag with npm install or set the\nnpm_config_arch environment variable:\nnpm install --arch=ia32 electron\n\nIn addition to changing the architecture, you can also specify the platform\n(e.g., win32, linux, etc.) using the --platform flag:\nnpm install --platform=win32 electron\n\n\nProxies\nIf you need to use an HTTP proxy, you need to set the ELECTRON_GET_USE_PROXY variable to any\nvalue, plus additional environment variables depending on your host system's Node version:\n\nNode 10 and above\nBefore Node 10\n\n\nCustom Mirrors and Caches\nDuring installation, the electron module will call out to\n@electron/get to download prebuilt binaries of\nElectron for your platform. It will do so by contacting GitHub's\nrelease download page (https://github.com/electron/electron/releases/tag/v$VERSION,\nwhere $VERSION is the exact version of Electron).\nIf you are unable to access GitHub or you need to provide a custom build, you\ncan do so by either providing a mirror or an existing cache directory.\n\nMirror\nYou can use environment variables to override the base URL, the path at which to\nlook for Electron binaries, and the binary filename. The URL used by @electron/get\nis composed as follows:\nurl = ELECTRON_MIRROR + ELECTRON_CUSTOM_DIR + '/' + ELECTRON_CUSTOM_FILENAME\n\nFor instance, to use the China CDN mirror:\nELECTRON_MIRROR=\"https://cdn.npm.taobao.org/dist/electron/\"\n\nBy default, ELECTRON_CUSTOM_DIR is set to v$VERSION. To change the format,\nuse the {{ version }} placeholder. For example, version-{{ version }}\nresolves to version-5.0.0, {{ version }} resolves to 5.0.0, and\nv{{ version }} is equivalent to the default. As a more concrete example, to\nuse the China non-CDN mirror:\nELECTRON_MIRROR=\"https://npm.taobao.org/mirrors/electron/\"\nELECTRON_CUSTOM_DIR=\"{{ version }}\"\n\nThe above configuration will download from URLs such as\nhttps://npm.taobao.org/mirrors/electron/8.0.0/electron-v8.0.0-linux-x64.zip.\n\nCache\nAlternatively, you can override the local cache. @electron/get will cache\ndownloaded binaries in a local directory to not stress your network. You can use\nthat cache folder to provide custom builds of Electron or to avoid making contact\nwith the network at all.\n\nLinux: $XDG_CACHE_HOME or ~/.cache/electron/\nmacOS: ~/Library/Caches/electron/\nWindows: $LOCALAPPDATA/electron/Cache or ~/AppData/Local/electron/Cache/\n\nOn environments that have been using older versions of Electron, you might find the\ncache also in ~/.electron.\nYou can also override the local cache location by providing a electron_config_cache\nenvironment variable.\nThe cache contains the version's official zip file as well as a checksum, stored as\na text file. A typical cache might look like this:\n├── httpsgithub.comelectronelectronreleasesdownloadv1.7.9electron-v1.7.9-darwin-x64.zip\n│ └── electron-v1.7.9-darwin-x64.zip\n├── httpsgithub.comelectronelectronreleasesdownloadv1.7.9SHASUMS256.txt\n│ └── SHASUMS256.txt\n├── httpsgithub.comelectronelectronreleasesdownloadv1.8.1electron-v1.8.1-darwin-x64.zip\n│ └── electron-v1.8.1-darwin-x64.zip\n├── httpsgithub.comelectronelectronreleasesdownloadv1.8.1SHASUMS256.txt\n│ └── SHASUMS256.txt\n├── httpsgithub.comelectronelectronreleasesdownloadv1.8.2-beta.1electron-v1.8.2-beta.1-darwin-x64.zip\n│ └── electron-v1.8.2-beta.1-darwin-x64.zip\n├── httpsgithub.comelectronelectronreleasesdownloadv1.8.2-beta.1SHASUMS256.txt\n│ └── SHASUMS256.txt\n├── httpsgithub.comelectronelectronreleasesdownloadv1.8.2-beta.2electron-v1.8.2-beta.2-darwin-x64.zip\n│ └── electron-v1.8.2-beta.2-darwin-x64.zip\n├── httpsgithub.comelectronelectronreleasesdownloadv1.8.2-beta.2SHASUMS256.txt\n│ └── SHASUMS256.txt\n├── httpsgithub.comelectronelectronreleasesdownloadv1.8.2-beta.3electron-v1.8.2-beta.3-darwin-x64.zip\n│ └── electron-v1.8.2-beta.3-darwin-x64.zip\n└── httpsgithub.comelectronelectronreleasesdownloadv1.8.2-beta.3SHASUMS256.txt\n └── SHASUMS256.txt\n\n\nSkip binary download\nWhen installing the electron NPM package, it automatically downloads the electron binary.\nThis can sometimes be unnecessary, e.g. in a CI environment, when testing another component.\nTo prevent the binary from being downloaded when you install all npm dependencies you can set the environment variable ELECTRON_SKIP_BINARY_DOWNLOAD.\nE.g.:\nELECTRON_SKIP_BINARY_DOWNLOAD=1 npm install\n\n\nTroubleshooting\nWhen running npm install electron, some users occasionally encounter\ninstallation errors.\nIn almost all cases, these errors are the result of network problems and not\nactual issues with the electron npm package. Errors like ELIFECYCLE,\nEAI_AGAIN, ECONNRESET, and ETIMEDOUT are all indications of such\nnetwork problems. The best resolution is to try switching networks, or\nwait a bit and try installing again.\nYou can also attempt to download Electron directly from\nelectron/electron/releases\nif installing via npm is failing.\nIf installation fails with an EACCESS error you may need to\nfix your npm permissions.\nIf the above error persists, the unsafe-perm flag may need to be\nset to true:\nsudo npm install electron --unsafe-perm=true\n\nOn slower networks, it may be advisable to use the --verbose flag in order to\nshow download progress:\nnpm install --verbose electron\n\nIf you need to force a re-download of the asset and the SHASUM file set the\nforce_no_cache environment variable to true.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Installation",
"doc:installation",
"tutorial:Installation",
"tutorial:installation"
]
},
{
"objectID": "tutorial-issues",
"title": "Issues In Electron",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/development/issues.md",
"url": "https://electronjs.org/docs/development/issues",
"slug": "issues",
"body": "Issues In Electron\n\nHow to Contribute to Issues\nAsking for General Help\nSubmitting a Bug Report\nTriaging a Bug Report\nResolving a Bug Report\n\n\nHow to Contribute to Issues\nFor any issue, there are fundamentally three ways an individual can\ncontribute:\n\nBy opening the issue for discussion: If you believe that you have found\na new bug in Electron, you should report it by creating a new issue in\nthe electron/electron issue tracker.\nBy helping to triage the issue: You can do this either by providing\nassistive details (a reproducible test case that demonstrates a bug) or by\nproviding suggestions to address the issue.\nBy helping to resolve the issue: This can be done by demonstrating\nthat the issue is not a bug or is fixed; but more often, by opening\na pull request that changes the source in electron/electron in a\nconcrete and reviewable manner.\n\n\nAsking for General Help\n\"Finding Support\" has a\nlist of resources for getting programming help, reporting security issues,\ncontributing, and more. Please use the issue tracker for bugs only!\n\nSubmitting a Bug Report\nTo submit a bug report:\nWhen opening a new issue in the electron/electron issue tracker, users\nwill be presented with a template that should be filled in.\nIf you believe that you have found a bug in Electron, please fill out the template\nto the best of your ability.\nThe two most important pieces of information needed to evaluate the report are\na description of the bug and a simple test case to recreate it. It is easier to fix\na bug if it can be reproduced.\nSee How to create a Minimal, Complete, and Verifiable example.\n\nTriaging a Bug Report\nIt's common for open issues to involve discussion. Some contributors may\nhave differing opinions, including whether the behavior is a bug or feature.\nThis discussion is part of the process and should be kept focused, helpful,\nand professional.\nTerse responses that provide neither additional context nor supporting detail\nare not helpful or professional. To many, such responses are annoying and\nunfriendly.\nContributors are encouraged to solve issues collaboratively and help one\nanother make progress. If you encounter an issue that you feel is invalid, or\nwhich contains incorrect information, explain why you feel that way with\nadditional supporting context, and be willing to be convinced that you may\nbe wrong. By doing so, we can often reach the correct outcome faster.\n\nResolving a Bug Report\nMost issues are resolved by opening a pull request. The process for opening and\nreviewing a pull request is similar to that of opening and triaging issues, but\ncarries with it a necessary review and approval workflow that ensures that the\nproposed changes meet the minimal quality and functional guidelines of the\nElectron project.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Issues In Electron",
"doc:issues",
"tutorial:Issues In Electron",
"tutorial:issues"
]
},
{
"objectID": "tutorial-keyboard-shortcuts",
"title": "Keyboard Shortcuts",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/keyboard-shortcuts.md",
"url": "https://electronjs.org/docs/tutorial/keyboard-shortcuts",
"slug": "keyboard-shortcuts",
"body": "Keyboard Shortcuts\n\nOverview\nThis feature allows you to configure local and global keyboard shortcuts\nfor your Electron application.\n\nExample\n\nLocal Shortcuts\nLocal keyboard shortcuts are triggered only when the application is focused.\nTo configure a local keyboard shortcut, you need to specify an accelerator\nproperty when creating a MenuItem within the Menu module.\nStarting with a working application from the\nQuick Start Guide, update the main.js file with the\nfollowing lines:\nconst { Menu, MenuItem } = require('electron')\n\nconst menu = new Menu()\nmenu.append(new MenuItem({\n label: 'Electron',\n submenu: [{\n role: 'help',\n accelerator: process.platform === 'darwin' ? 'Alt+Cmd+I' : 'Alt+Shift+I',\n click: () => { console.log('Electron rocks!') }\n }]\n}))\n\nMenu.setApplicationMenu(menu)\n\n\nNOTE: In the code above, you can see that the accelerator differs based on the\nuser's operating system. For MacOS, it is Alt+Cmd+I, whereas for Linux and\nWindows, it is Alt+Shift+I.\n\nAfter launching the Electron application, you should see the application menu\nalong with the local shortcut you just defined:\n\nIf you click Help or press the defined accelerator and then open the terminal\nthat you ran your Electron application from, you will see the message that was\ngenerated after triggering the click event: \"Electron rocks!\".\n\nGlobal Shortcuts\nTo configure a global keyboard shortcut, you need to use the globalShortcut\nmodule to detect keyboard events even when the application does not have\nkeyboard focus.\nStarting with a working application from the\nQuick Start Guide, update the main.js file with the\nfollowing lines:\nconst { app, globalShortcut } = require('electron')\n\napp.whenReady().then(() => {\n globalShortcut.register('Alt+CommandOrControl+I', () => {\n console.log('Electron loves global shortcuts!')\n })\n}).then(createWindow)\n\n\nNOTE: In the code above, the CommandOrControl combination uses Command\non macOS and Control on Windows/Linux.\n\nAfter launching the Electron application, if you press the defined key\ncombination then open the terminal that you ran your Electron application from,\nyou will see that Electron loves global shortcuts!\n\nShortcuts within a BrowserWindow\n\nUsing web APIs\nIf you want to handle keyboard shortcuts within a BrowserWindow, you can\nlisten for the keyup and keydown DOM events inside the\nrenderer process using the addEventListener() API.\nwindow.addEventListener('keyup', doSomething, true)\n\nNote the third parameter true indicates that the listener will always receive\nkey presses before other listeners so they can't have stopPropagation()\ncalled on them.\n\nIntercepting events in the main process\nThe before-input-event event\nis emitted before dispatching keydown and keyup events in the page. It can\nbe used to catch and handle custom shortcuts that are not visible in the menu.\n\nExample\nStarting with a working application from the\nQuick Start Guide, update the main.js file with the\nfollowing lines:\nconst { app, BrowserWindow } = require('electron')\n\napp.whenReady().then(() => {\n const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true } })\n\n win.loadFile('index.html')\n win.webContents.on('before-input-event', (event, input) => {\n if (input.control && input.key.toLowerCase() === 'i') {\n console.log('Pressed Control+I')\n event.preventDefault()\n }\n })\n})\n\nAfter launching the Electron application, if you open the terminal that you ran\nyour Electron application from and press Ctrl+I key combination, you will\nsee that this key combination was successfully intercepted.\n\nUsing third-party libraries\nIf you don't want to do manual shortcut parsing, there are libraries that do\nadvanced key detection, such as mousetrap. Below are examples of usage of the\nmousetrap running in the Renderer process:\nMousetrap.bind('4', () => { console.log('4') })\nMousetrap.bind('?', () => { console.log('show shortcuts!') })\nMousetrap.bind('esc', () => { console.log('escape') }, 'keyup')\n\n// combinations\nMousetrap.bind('command+shift+k', () => { console.log('command shift k') })\n\n// map multiple combinations to the same callback\nMousetrap.bind(['command+k', 'ctrl+k'], () => {\n console.log('command k or control k')\n\n // return false to prevent default behavior and stop event from bubbling\n return false\n})\n\n// gmail style sequences\nMousetrap.bind('g i', () => { console.log('go to inbox') })\nMousetrap.bind('* a', () => { console.log('select all') })\n\n// konami code!\nMousetrap.bind('up up down down left right left right b a enter', () => {\n console.log('konami code')\n})\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Keyboard Shortcuts",
"doc:keyboard-shortcuts",
"tutorial:Keyboard Shortcuts",
"tutorial:keyboard-shortcuts"
]
},
{
"objectID": "tutorial-linux-desktop-actions",
"title": "Custom Linux Desktop Launcher Actions",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/linux-desktop-actions.md",
"url": "https://electronjs.org/docs/tutorial/linux-desktop-actions",
"slug": "linux-desktop-actions",
"body": "Custom Linux Desktop Launcher Actions\n\nOverview\nOn many Linux environments, you can add custom entries to the system launcher\nby modifying the .desktop file. For Canonical's Unity documentation, see\nAdding Shortcuts to a Launcher. For details on a more generic\nimplementation, see the freedesktop.org Specification.\n\n\nNOTE: The screenshot above is an example of launcher shortcuts in Audacious\naudio player\n\nTo create a shortcut, you need to provide Name and Exec properties for the\nentry you want to add to the shortcut menu. Unity will execute the command\ndefined in the Exec field after the user clicked the shortcut menu item.\nAn example of the .desktop file may look as follows:\nActions=PlayPause;Next;Previous\n\n[Desktop Action PlayPause]\nName=Play-Pause\nExec=audacious -t\nOnlyShowIn=Unity;\n\n[Desktop Action Next]\nName=Next\nExec=audacious -f\nOnlyShowIn=Unity;\n\n[Desktop Action Previous]\nName=Previous\nExec=audacious -r\nOnlyShowIn=Unity;\n\nThe preferred way for Unity to instruct your application on what to do is using\nparameters. You can find them in your application in the global variable\nprocess.argv.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Custom Linux Desktop Launcher Actions",
"doc:linux-desktop-actions",
"tutorial:Custom Linux Desktop Launcher Actions",
"tutorial:linux-desktop-actions"
]
},
{
"objectID": "tutorial-mac-app-store-submission-guide",
"title": "Mac App Store Submission Guide",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/mac-app-store-submission-guide.md",
"url": "https://electronjs.org/docs/tutorial/mac-app-store-submission-guide",
"slug": "mac-app-store-submission-guide",
"body": "Mac App Store Submission Guide\nSince v0.34.0, Electron allows submitting packaged apps to the Mac App Store\n(MAS). This guide provides information on: how to submit your app and the\nlimitations of the MAS build.\nNote: Submitting an app to Mac App Store requires enrolling in the Apple Developer\nProgram, which costs money.\n\nHow to Submit Your App\nThe following steps introduce a simple way to submit your app to Mac App Store.\nHowever, these steps do not ensure your app will be approved by Apple; you\nstill need to read Apple's Submitting Your App guide on\nhow to meet the Mac App Store requirements.\n\nGet Certificate\nTo submit your app to the Mac App Store, you first must get a certificate from\nApple. You can follow these existing guides on web.\n\nGet Team ID\nBefore signing your app, you need to know the Team ID of your account. To locate\nyour Team ID, Sign in to Apple Developer Center,\nand click Membership in the sidebar. Your Team ID appears in the Membership\nInformation section under the team name.\n\nSign Your App\nAfter finishing the preparation work, you can package your app by following\nApplication Distribution, and then proceed to\nsigning your app.\nFirst, you have to add a ElectronTeamID key to your app's Info.plist, which\nhas your Team ID as its value:\n<plist version=\"1.0\">\n<dict>\n ...\n <key>ElectronTeamID</key>\n <string>TEAM_ID</string>\n</dict>\n</plist>\n\nThen, you need to prepare three entitlements files.\nchild.plist:\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n <dict>\n <key>com.apple.security.app-sandbox</key>\n <true/>\n <key>com.apple.security.inherit</key>\n <true/>\n </dict>\n</plist>\n\nparent.plist:\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n <dict>\n <key>com.apple.security.app-sandbox</key>\n <true/>\n <key>com.apple.security.application-groups</key>\n <array>\n <string>TEAM_ID.your.bundle.id</string>\n </array>\n </dict>\n</plist>\n\nloginhelper.plist:\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n <dict>\n <key>com.apple.security.app-sandbox</key>\n <true/>\n </dict>\n</plist>\n\nYou have to replace TEAM_ID with your Team ID, and replace your.bundle.id\nwith the Bundle ID of your app.\nAnd then sign your app with the following script:\n#!/bin/bash\n\n# Name of your app.\nAPP=\"YourApp\"\n# The path of your app to sign.\nAPP_PATH=\"/path/to/YourApp.app\"\n# The path to the location you want to put the signed package.\nRESULT_PATH=\"~/Desktop/$APP.pkg\"\n# The name of certificates you requested.\nAPP_KEY=\"3rd Party Mac Developer Application: Company Name (APPIDENTITY)\"\nINSTALLER_KEY=\"3rd Party Mac Developer Installer: Company Name (APPIDENTITY)\"\n# The path of your plist files.\nCHILD_PLIST=\"/path/to/child.plist\"\nPARENT_PLIST=\"/path/to/parent.plist\"\nLOGINHELPER_PLIST=\"/path/to/loginhelper.plist\"\n\nFRAMEWORKS_PATH=\"$APP_PATH/Contents/Frameworks\"\n\ncodesign -s \"$APP_KEY\" -f --entitlements \"$CHILD_PLIST\" \"$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Electron Framework\"\ncodesign -s \"$APP_KEY\" -f --entitlements \"$CHILD_PLIST\" \"$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Libraries/libffmpeg.dylib\"\ncodesign -s \"$APP_KEY\" -f --entitlements \"$CHILD_PLIST\" \"$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Libraries/libnode.dylib\"\ncodesign -s \"$APP_KEY\" -f --entitlements \"$CHILD_PLIST\" \"$FRAMEWORKS_PATH/Electron Framework.framework\"\ncodesign -s \"$APP_KEY\" -f --entitlements \"$CHILD_PLIST\" \"$FRAMEWORKS_PATH/$APP Helper.app/Contents/MacOS/$APP Helper\"\ncodesign -s \"$APP_KEY\" -f --entitlements \"$CHILD_PLIST\" \"$FRAMEWORKS_PATH/$APP Helper.app/\"\ncodesign -s \"$APP_KEY\" -f --entitlements \"$LOGINHELPER_PLIST\" \"$APP_PATH/Contents/Library/LoginItems/$APP Login Helper.app/Contents/MacOS/$APP Login Helper\"\ncodesign -s \"$APP_KEY\" -f --entitlements \"$LOGINHELPER_PLIST\" \"$APP_PATH/Contents/Library/LoginItems/$APP Login Helper.app/\"\ncodesign -s \"$APP_KEY\" -f --entitlements \"$CHILD_PLIST\" \"$APP_PATH/Contents/MacOS/$APP\"\ncodesign -s \"$APP_KEY\" -f --entitlements \"$PARENT_PLIST\" \"$APP_PATH\"\n\nproductbuild --component \"$APP_PATH\" /Applications --sign \"$INSTALLER_KEY\" \"$RESULT_PATH\"\n\nIf you are new to app sandboxing under macOS, you should also read through\nApple's Enabling App Sandbox to have a basic idea, then\nadd keys for the permissions needed by your app to the entitlements files.\nApart from manually signing your app, you can also choose to use the\nelectron-osx-sign module to do the job.\n\nSign Native Modules\nNative modules used in your app also need to be signed. If using\nelectron-osx-sign, be sure to include the path to the built binaries in the\nargument list:\nelectron-osx-sign YourApp.app YourApp.app/Contents/Resources/app/node_modules/nativemodule/build/release/nativemodule\n\nAlso note that native modules may have intermediate files produced which should\nnot be included (as they would also need to be signed). If you use\nelectron-packager before version 8.1.0, add\n--ignore=.+\\.o$ to your build step to ignore these files. Versions 8.1.0 and\nlater ignore those files by default.\n\nUpload Your App\nAfter signing your app, you can use Application Loader to upload it to iTunes\nConnect for processing, making sure you have created a record\nbefore uploading.\n\nSubmit Your App for Review\nAfter these steps, you can submit your app for review.\n\nLimitations of MAS Build\nIn order to satisfy all requirements for app sandboxing, the following modules\nhave been disabled in the MAS build:\n\ncrashReporter\nautoUpdater\n\nand the following behaviors have been changed:\n\nVideo capture may not work for some machines.\nCertain accessibility features may not work.\nApps will not be aware of DNS changes.\n\nAlso, due to the usage of app sandboxing, the resources which can be accessed by\nthe app are strictly limited; you can read App Sandboxing for\nmore information.\n\nAdditional Entitlements\nDepending on which Electron APIs your app uses, you may need to add additional\nentitlements to your parent.plist file to be able to use these APIs from your\napp's Mac App Store build.\n\nNetwork Access\nEnable outgoing network connections to allow your app to connect to a server:\n<key>com.apple.security.network.client</key>\n<true/>\n\nEnable incoming network connections to allow your app to open a network\nlistening socket:\n<key>com.apple.security.network.server</key>\n<true/>\n\nSee the Enabling Network Access documentation for more\ndetails.\n\ndialog.showOpenDialog\n<key>com.apple.security.files.user-selected.read-only</key>\n<true/>\n\nSee the Enabling User-Selected File Access documentation for\nmore details.\n\ndialog.showSaveDialog\n<key>com.apple.security.files.user-selected.read-write</key>\n<true/>\n\nSee the Enabling User-Selected File Access documentation for\nmore details.\n\nCryptographic Algorithms Used by Electron\nDepending on the countries in which you are releasing your app, you may be\nrequired to provide information on the cryptographic algorithms used in your\nsoftware. See the encryption export compliance docs for\nmore information.\nElectron uses following cryptographic algorithms:\n\nAES - NIST SP 800-38A, NIST SP 800-38D, RFC 3394\nHMAC - FIPS 198-1\nECDSA - ANS X9.62–2005\nECDH - ANS X9.63–2001\nHKDF - NIST SP 800-56C\nPBKDF2 - RFC 2898\nRSA - RFC 3447\nSHA - FIPS 180-4\nBlowfish - https://www.schneier.com/cryptography/blowfish/\nCAST - RFC 2144, RFC 2612\nDES - FIPS 46-3\nDH - RFC 2631\nDSA - ANSI X9.30\nEC - SEC 1\nIDEA - \"On the Design and Security of Block Ciphers\" book by X. Lai\nMD2 - RFC 1319\nMD4 - RFC 6150\nMD5 - RFC 1321\nMDC2 - ISO/IEC 10118-2\nRC2 - RFC 2268\nRC4 - RFC 4345\nRC5 - https://people.csail.mit.edu/rivest/Rivest-rc5rev.pdf\nRIPEMD - ISO/IEC 10118-3\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Mac App Store Submission Guide",
"doc:mac-app-store-submission-guide",
"tutorial:Mac App Store Submission Guide",
"tutorial:mac-app-store-submission-guide"
]
},
{
"objectID": "tutorial-macos-dock",
"title": "macOS Dock",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/macos-dock.md",
"url": "https://electronjs.org/docs/tutorial/macos-dock",
"slug": "macos-dock",
"body": "macOS Dock\n\nOverview\nElectron has APIs to configure the app's icon in the macOS Dock. A macOS-only\nAPI exists to create a custom dock menu, but Electron also uses the app dock\nicon as the entry point for cross-platform features like\nrecent documents and application progress.\nThe custom dock is commonly used to add shortcuts to tasks the user wouldn't\nwant to open the whole app window for.\nDock menu of Terminal.app:\n\nTo set your custom dock menu, you need to use the\napp.dock.setMenu API,\nwhich is only available on macOS.\n\nExample\nStarting with a working application from the\nQuick Start Guide, update the main.js file with the\nfollowing lines:\nconst { app, Menu } = require('electron')\n\nconst dockMenu = Menu.buildFromTemplate([\n {\n label: 'New Window',\n click () { console.log('New Window') }\n }, {\n label: 'New Window with Settings',\n submenu: [\n { label: 'Basic' },\n { label: 'Pro' }\n ]\n },\n { label: 'New Command...' }\n])\n\napp.whenReady().then(() => {\n app.dock.setMenu(dockMenu)\n})\n\nAfter launching the Electron application, right click the application icon.\nYou should see the custom menu you just defined:\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:macOS Dock",
"doc:macos-dock",
"tutorial:macOS Dock",
"tutorial:macos-dock"
]
},
{
"objectID": "tutorial-message-ports",
"title": "MessagePorts in Electron",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/message-ports.md",
"url": "https://electronjs.org/docs/tutorial/message-ports",
"slug": "message-ports",
"body": "MessagePorts in Electron\nMessagePorts are a web feature that allow passing messages between\ndifferent contexts. It's like window.postMessage, but on different channels.\nThe goal of this document is to describe how Electron extends the Channel\nMessaging model, and to give some examples of how you might use MessagePorts in\nyour app.\nHere is a very brief example of what a MessagePort is and how it works:\n// renderer.js ///////////////////////////////////////////////////////////////\n// MessagePorts are created in pairs. A connected pair of message ports is\n// called a channel.\nconst channel = new MessageChannel()\n\n// The only difference between port1 and port2 is in how you use them. Messages\n// sent to port1 will be received by port2 and vice-versa.\nconst port1 = channel.port1\nconst port2 = channel.port2\n\n// It's OK to send a message on the channel before the other end has registered\n// a listener. Messages will be queued until a listener is registered.\nport2.postMessage({ answer: 42 })\n\n// Here we send the other end of the channel, port1, to the main process. It's\n// also possible to send MessagePorts to other frames, or to Web Workers, etc.\nipcRenderer.postMessage('port', null, [port1])\n\n// main.js ///////////////////////////////////////////////////////////////////\n// In the main process, we receive the port.\nipcMain.on('port', (event) => {\n // When we receive a MessagePort in the main process, it becomes a\n // MessagePortMain.\n const port = event.ports[0]\n\n // MessagePortMain uses the Node.js-style events API, rather than the\n // web-style events API. So .on('message', ...) instead of .onmessage = ...\n port.on('message', (event) => {\n // data is { answer: 42 }\n const data = event.data\n })\n\n // MessagePortMain queues messages until the .start() method has been called.\n port.start()\n})\n\nThe Channel Messaging API documentation is a great way to learn more about\nhow MessagePorts work.\n\nMessagePorts in the main process\nIn the renderer, the MessagePort class behaves exactly as it does on the web.\nThe main process is not a web page, though—it has no Blink integration—and so\nit does not have the MessagePort or MessageChannel classes. In order to\nhandle and interact with MessagePorts in the main process, Electron adds two\nnew classes: MessagePortMain and MessageChannelMain. These behave\nsimilarly to the analogous classes in the renderer.\nMessagePort objects can be created in either the renderer or the main\nprocess, and passed back and forth using the ipcRenderer.postMessage and\nWebContents.postMessage methods. Note that the usual IPC methods like\nsend and invoke cannot be used to transfer MessagePorts, only the\npostMessage methods can transfer MessagePorts.\nBy passing MessagePorts via the main process, you can connect two pages that\nmight not otherwise be able to communicate (e.g. due to same-origin\nrestrictions).\n\nExtension: close event\nElectron adds one feature to MessagePort that isn't present on the web, in\norder to make MessagePorts more useful. That is the close event, which is\nemitted when the other end of the channel is closed. Ports can also be\nimplicitly closed by being garbage-collected.\nIn the renderer, you can listen for the close event either by assigning to\nport.onclose or by calling port.addEventListener('close', ...). In the main\nprocess, you can listen for the close event by calling port.on('close', ...).\n\nExample use cases\n\nWorker process\nIn this example, your app has a worker process implemented as a hidden window.\nYou want the app page to be able to communicate directly with the worker\nprocess, without the performance overhead of relaying via the main process.\n// main.js ///////////////////////////////////////////////////////////////////\nconst { BrowserWindow, app, ipcMain, MessageChannelMain } = require('electron')\n\napp.whenReady().then(async () => {\n // The worker process is a hidden BrowserWindow, so that it will have access\n // to a full Blink context (including e.g. <canvas>, audio, fetch(), etc.)\n const worker = new BrowserWindow({\n show: false,\n webPreferences: { nodeIntegration: true }\n })\n await worker.loadFile('worker.html')\n\n // The main window will send work to the worker process and receive results\n // over a MessagePort.\n const mainWindow = new BrowserWindow({\n webPreferences: { nodeIntegration: true }\n })\n mainWindow.loadFile('app.html')\n\n // We can't use ipcMain.handle() here, because the reply needs to transfer a\n // MessagePort.\n ipcMain.on('request-worker-channel', (event) => {\n // For security reasons, let's make sure only the frames we expect can\n // access the worker.\n if (event.senderFrame === mainWindow.webContents.mainFrame) {\n // Create a new channel ...\n const { port1, port2 } = new MessageChannelMain()\n // ... send one end to the worker ...\n worker.webContents.postMessage('new-client', null, [port1])\n // ... and the other end to the main window.\n event.senderFrame.postMessage('provide-worker-channel', null, [port2])\n // Now the main window and the worker can communicate with each other\n // without going through the main process!\n }\n })\n})\n\n<!-- worker.html ------------------------------------------------------------>\n<script>\nconst { ipcRenderer } = require('electron')\n\nfunction doWork(input) {\n // Something cpu-intensive.\n return input * 2\n}\n\n// We might get multiple clients, for instance if there are multiple windows,\n// or if the main window reloads.\nipcRenderer.on('new-client', (event) => {\n const [ port ] = event.ports\n port.onmessage = (event) => {\n // The event data can be any serializable object (and the event could even\n // carry other MessagePorts with it!)\n const result = doWork(event.data)\n port.postMessage(result)\n }\n})\n</script>\n\n<!-- app.html --------------------------------------------------------------->\n<script>\nconst { ipcRenderer } = require('electron')\n\n// We request that the main process sends us a channel we can use to\n// communicate with the worker.\nipcRenderer.send('request-worker-channel')\n\nipcRenderer.once('provide-worker-channel', (event) => {\n // Once we receive the reply, we can take the port...\n const [ port ] = event.ports\n // ... register a handler to receive results ...\n port.onmessage = (event) => {\n console.log('received result:', event.data)\n }\n // ... and start sending it work!\n port.postMessage(21)\n})\n</script>\n\n\nReply streams\nElectron's built-in IPC methods only support two modes: fire-and-forget\n(e.g. send), or request-response (e.g. invoke). Using MessageChannels, you\ncan implement a \"response stream\", where a single request responds with a\nstream of data.\n// renderer.js ///////////////////////////////////////////////////////////////\n\nfunction makeStreamingRequest (element, callback) {\n // MessageChannels are lightweight--it's cheap to create a new one for each\n // request.\n const { port1, port2 } = new MessageChannel()\n\n // We send one end of the port to the main process ...\n ipcRenderer.postMessage(\n 'give-me-a-stream',\n { element, count: 10 },\n [port2]\n )\n\n // ... and we hang on to the other end. The main process will send messages\n // to its end of the port, and close it when it's finished.\n port1.onmessage = (event) => {\n callback(event.data)\n }\n port1.onclose = () => {\n console.log('stream ended')\n }\n}\n\nmakeStreamingRequest(42, (data) => {\n console.log('got response data:', event.data)\n})\n// We will see \"got response data: 42\" 10 times.\n\n// main.js ///////////////////////////////////////////////////////////////////\n\nipcMain.on('give-me-a-stream', (event, msg) => {\n // The renderer has sent us a MessagePort that it wants us to send our\n // response over.\n const [replyPort] = event.ports\n\n // Here we send the messages synchronously, but we could just as easily store\n // the port somewhere and send messages asynchronously.\n for (let i = 0; i < msg.count; i++) {\n replyPort.postMessage(msg.element)\n }\n\n // We close the port when we're done to indicate to the other end that we\n // won't be sending any more messages. This isn't strictly necessary--if we\n // didn't explicitly close the port, it would eventually be garbage\n // collected, which would also trigger the 'close' event in the renderer.\n replyPort.close()\n})\n\n\nCommunicating directly between the main process and the main world of a context-isolated page\nWhen context isolation is enabled, IPC messages from the main process to\nthe renderer are delivered to the isolated world, rather than to the main\nworld. Sometimes you want to deliver messages to the main world directly,\nwithout having to step through the isolated world.\n// main.js ///////////////////////////////////////////////////////////////////\nconst { BrowserWindow, app, MessageChannelMain } = require('electron')\nconst path = require('path')\n\napp.whenReady().then(async () => {\n // Create a BrowserWindow with contextIsolation enabled.\n const bw = new BrowserWindow({\n webPreferences: {\n contextIsolation: true,\n preload: path.join(__dirname, 'preload.js')\n }\n })\n bw.loadURL('index.html')\n\n // We'll be sending one end of this channel to the main world of the\n // context-isolated page.\n const { port1, port2 } = new MessageChannelMain()\n\n // It's OK to send a message on the channel before the other end has\n // registered a listener. Messages will be queued until a listener is\n // registered.\n port2.postMessage({ test: 21 })\n\n // We can also receive messages from the main world of the renderer.\n port2.on('message', (event) => {\n console.log('from renderer main world:', event.data)\n })\n port2.start()\n\n // The preload script will receive this IPC message and transfer the port\n // over to the main world.\n bw.webContents.postMessage('main-world-port', null, [port1])\n})\n\n// preload.js ////////////////////////////////////////////////////////////////\nconst { ipcRenderer } = require('electron')\n\n// We need to wait until the main world is ready to receive the message before\n// sending the port. We create this promise in the preload so it's guaranteed\n// to register the onload listener before the load event is fired.\nconst windowLoaded = new Promise(resolve => {\n window.onload = resolve\n})\n\nipcRenderer.on('main-world-port', async (event) => {\n await windowLoaded\n // We use regular window.postMessage to transfer the port from the isolated\n // world to the main world.\n window.postMessage('main-world-port', '*', event.ports)\n})\n\n<!-- index.html ------------------------------------------------------------->\n<script>\nwindow.onmessage = (event) => {\n // event.source === window means the message is coming from the preload\n // script, as opposed to from an <iframe> or other source.\n if (event.source === window && event.data === 'main-world-port') {\n const [ port ] = event.ports\n // Once we have the port, we can communicate directly with the main\n // process.\n port.onmessage = (event) => {\n console.log('from main process:', event.data)\n port.postMessage(event.data * 2)\n }\n }\n}\n</script>\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:MessagePorts in Electron",
"doc:message-ports",
"tutorial:MessagePorts in Electron",
"tutorial:message-ports"
]
},
{
"objectID": "tutorial-multithreading",
"title": "Multithreading",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/multithreading.md",
"url": "https://electronjs.org/docs/tutorial/multithreading",
"slug": "multithreading",
"body": "Multithreading\nWith Web Workers, it is possible to run JavaScript in OS-level\nthreads.\n\nMulti-threaded Node.js\nIt is possible to use Node.js features in Electron's Web Workers, to do\nso the nodeIntegrationInWorker option should be set to true in\nwebPreferences.\nconst win = new BrowserWindow({\n webPreferences: {\n nodeIntegrationInWorker: true\n }\n})\n\nThe nodeIntegrationInWorker can be used independent of nodeIntegration, but\nsandbox must not be set to true.\n\nAvailable APIs\nAll built-in modules of Node.js are supported in Web Workers, and asar\narchives can still be read with Node.js APIs. However none of Electron's\nbuilt-in modules can be used in a multi-threaded environment.\n\nNative Node.js modules\nAny native Node.js module can be loaded directly in Web Workers, but it is\nstrongly recommended not to do so. Most existing native modules have been\nwritten assuming single-threaded environment, using them in Web Workers will\nlead to crashes and memory corruptions.\nNote that even if a native Node.js module is thread-safe it's still not safe to\nload it in a Web Worker because the process.dlopen function is not thread\nsafe.\nThe only way to load a native module safely for now, is to make sure the app\nloads no native modules after the Web Workers get started.\nprocess.dlopen = () => {\n throw new Error('Load native module is not safe')\n}\nconst worker = new Worker('script.js')\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Multithreading",
"doc:multithreading",
"tutorial:Multithreading",
"tutorial:multithreading"
]
},
{
"objectID": "tutorial-native-file-drag-drop",
"title": "Native File Drag & Drop",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/native-file-drag-drop.md",
"url": "https://electronjs.org/docs/tutorial/native-file-drag-drop",
"slug": "native-file-drag-drop",
"body": "Native File Drag & Drop\n\nOverview\nCertain kinds of applications that manipulate files might want to support\nthe operating system's native file drag & drop feature. Dragging files into\nweb content is common and supported by many websites. Electron additionally\nsupports dragging files and content out from web content into the operating\nsystem's world.\nTo implement this feature in your app, you need to call the\nwebContents.startDrag(item)\nAPI in response to the ondragstart event.\n\nExample\nStarting with a working application from the\nQuick Start Guide, add the following lines to the\nindex.html file:\n<a href=\"#\" id=\"drag\">Drag me</a>\n<script src=\"renderer.js\"></script>\n\nand add the following lines to the renderer.js file:\nconst { ipcRenderer } = require('electron')\n\ndocument.getElementById('drag').ondragstart = (event) => {\n event.preventDefault()\n ipcRenderer.send('ondragstart', '/absolute/path/to/the/item')\n}\n\nThe code above instructs the Renderer process to handle the ondragstart event\nand forward the information to the Main process.\nIn the Main process(main.js file), expand the received event with a path to the file that is\nbeing dragged and an icon:\nconst { ipcMain } = require('electron')\n\nipcMain.on('ondragstart', (event, filePath) => {\n event.sender.startDrag({\n file: filePath,\n icon: '/path/to/icon.png'\n })\n})\n\nAfter launching the Electron application, try dragging and dropping\nthe item from the BrowserWindow onto your desktop. In this guide,\nthe item is a Markdown file located in the root of the project:\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Native File Drag & Drop",
"doc:native-file-drag-drop",
"tutorial:Native File Drag & Drop",
"tutorial:native-file-drag-drop"
]
},
{
"objectID": "tutorial-notifications",
"title": "Notifications (Windows, Linux, macOS)",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/notifications.md",
"url": "https://electronjs.org/docs/tutorial/notifications",
"slug": "notifications",
"body": "Notifications (Windows, Linux, macOS)\n\nOverview\nAll three operating systems provide means for applications to send\nnotifications to the user. The technique of showing notifications is different\nfor the Main and Renderer processes.\nFor the Renderer process, Electron conveniently allows developers to send\nnotifications with the HTML5 Notification API,\nusing the currently running operating system's native notification APIs\nto display it.\nTo show notifications in the Main process, you need to use the\nNotification module.\n\nExample\n\nShow notifications in the Renderer process\nAssuming you have a working Electron application from the\nQuick Start Guide, add the following line to the\nindex.html file before the closing </body> tag:\n<script src=\"renderer.js\"></script>\n\nand add the renderer.js file:\nconst myNotification = new Notification('Title', {\n body: 'Notification from the Renderer process'\n})\n\nmyNotification.onclick = () => {\n console.log('Notification clicked')\n}\n\nAfter launching the Electron application, you should see the notification:\n\nIf you open the Console and then click the notification, you will see the\nmessage that was generated after triggering the onclick event:\n\n\nShow notifications in the Main process\nStarting with a working application from the\nQuick Start Guide, update the main.js file with the following lines:\nconst { Notification } = require('electron')\n\nfunction showNotification () {\n const notification = {\n title: 'Basic Notification',\n body: 'Notification from the Main process'\n }\n new Notification(notification).show()\n}\n\napp.whenReady().then(createWindow).then(showNotification)\n\nAfter launching the Electron application, you should see the notification:\n\n\nAdditional information\nWhile code and user experience across operating systems are similar, there\nare subtle differences.\n\nWindows\n\nOn Windows 10, a shortcut to your app with an\nApplication User Model ID must be installed to the\nStart Menu. This can be overkill during development, so adding\nnode_modules\\electron\\dist\\electron.exe to your Start Menu also does the\ntrick. Navigate to the file in Explorer, right-click and 'Pin to Start Menu'.\nYou will then need to add the line app.setAppUserModelId(process.execPath) to\nyour main process to see notifications.\nOn Windows 8.1 and Windows 8, a shortcut to your app with an Application User\nModel ID must be installed to the Start screen. Note,\nhowever, that it does not need to be pinned to the Start screen.\nOn Windows 7, notifications work via a custom implementation which visually\nresembles the native one on newer systems.\n\nElectron attempts to automate the work around the Application User Model ID. When\nElectron is used together with the installation and update framework Squirrel,\nshortcuts will automatically be set correctly. Furthermore,\nElectron will detect that Squirrel was used and will automatically call\napp.setAppUserModelId() with the correct value. During development, you may have\nto call app.setAppUserModelId() yourself.\nFurthermore, in Windows 8, the maximum length for the notification body is 250\ncharacters, with the Windows team recommending that notifications should be kept\nto 200 characters. That said, that limitation has been removed in Windows 10, with\nthe Windows team asking developers to be reasonable. Attempting to send gigantic\namounts of text to the API (thousands of characters) might result in instability.\n\nAdvanced Notifications\nLater versions of Windows allow for advanced notifications, with custom templates,\nimages, and other flexible elements. To send those notifications (from either the\nmain process or the renderer process), use the userland module\nelectron-windows-notifications,\nwhich uses native Node addons to send ToastNotification and TileNotification objects.\nWhile notifications including buttons work with electron-windows-notifications,\nhandling replies requires the use of\nelectron-windows-interactive-notifications,\nwhich helps with registering the required COM components and calling your\nElectron app with the entered user data.\n\nQuiet Hours / Presentation Mode\nTo detect whether or not you're allowed to send a notification, use the\nuserland module electron-notification-state.\nThis allows you to determine ahead of time whether or not Windows will\nsilently throw the notification away.\n\nmacOS\nNotifications are straight-forward on macOS, but you should be aware of\nApple's Human Interface guidelines regarding notifications.\nNote that notifications are limited to 256 bytes in size and will be truncated\nif you exceed that limit.\n\nAdvanced Notifications\nLater versions of macOS allow for notifications with an input field, allowing the user\nto quickly reply to a notification. In order to send notifications with an input field,\nuse the userland module node-mac-notifier.\n\nDo not disturb / Session State\nTo detect whether or not you're allowed to send a notification, use the userland module\nelectron-notification-state.\nThis will allow you to detect ahead of time whether or not the notification will be displayed.\n\nLinux\nNotifications are sent using libnotify which can show notifications on any\ndesktop environment that follows Desktop Notifications\nSpecification, including Cinnamon, Enlightenment, Unity,\nGNOME, KDE.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Notifications (Windows, Linux, macOS)",
"doc:notifications",
"tutorial:Notifications (Windows, Linux, macOS)",
"tutorial:notifications"
]
},
{
"objectID": "tutorial-offscreen-rendering",
"title": "Offscreen Rendering",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/offscreen-rendering.md",
"url": "https://electronjs.org/docs/tutorial/offscreen-rendering",
"slug": "offscreen-rendering",
"body": "Offscreen Rendering\n\nOverview\nOffscreen rendering lets you obtain the content of a BrowserWindow in a\nbitmap, so it can be rendered anywhere, for example, on texture in a 3D scene.\nThe offscreen rendering in Electron uses a similar approach to that of the\nChromium Embedded Framework\nproject.\nNotes:\n\nThere are two rendering modes that can be used (see the section below) and only\nthe dirty area is passed to the paint event to be more efficient.\nYou can stop/continue the rendering as well as set the frame rate.\nThe maximum frame rate is 240 because greater values bring only performance\nlosses with no benefits.\nWhen nothing is happening on a webpage, no frames are generated.\nAn offscreen window is always created as a\nFrameless Window.\n\n\nRendering Modes\n\nGPU accelerated\nGPU accelerated rendering means that the GPU is used for composition. Because of\nthat, the frame has to be copied from the GPU which requires more resources,\nthus this mode is slower than the Software output device. The benefit of this\nmode is that WebGL and 3D CSS animations are supported.\n\nSoftware output device\nThis mode uses a software output device for rendering in the CPU, so the frame\ngeneration is much faster. As a result, this mode is preferred over the GPU\naccelerated one.\nTo enable this mode, GPU acceleration has to be disabled by calling the\napp.disableHardwareAcceleration() API.\n\nExample\nStarting with a working application from the\nQuick Start Guide, add the following lines to the\nmain.js file:\nconst { app, BrowserWindow } = require('electron')\nconst fs = require('fs')\n\napp.disableHardwareAcceleration()\n\nlet win\n\napp.whenReady().then(() => {\n win = new BrowserWindow({ webPreferences: { offscreen: true } })\n\n win.loadURL('https://github.com')\n win.webContents.on('paint', (event, dirty, image) => {\n fs.writeFileSync('ex.png', image.toPNG())\n })\n win.webContents.setFrameRate(60)\n})\n\nAfter launching the Electron application, navigate to your application's\nworking folder.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Offscreen Rendering",
"doc:offscreen-rendering",
"tutorial:Offscreen Rendering",
"tutorial:offscreen-rendering"
]
},
{
"objectID": "tutorial-online-offline-events",
"title": "Online/Offline Event Detection",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/online-offline-events.md",
"url": "https://electronjs.org/docs/tutorial/online-offline-events",
"slug": "online-offline-events",
"body": "Online/Offline Event Detection\n\nOverview\nOnline and offline event\ndetection can be implemented in the Renderer process using the\nnavigator.onLine\nattribute, part of standard HTML5 API.\nThe navigator.onLine attribute returns:\n\nfalse if all network requests are guaranteed to fail (e.g. when disconnected from the network).\ntrue in all other cases.\n\nSince many cases return true, you should treat with care situations of\ngetting false positives, as we cannot always assume that true value means\nthat Electron can access the Internet. For example, in cases when the computer\nis running a virtualization software that has virtual Ethernet adapters in \"always\nconnected\" state. Therefore, if you want to determine the Internet access\nstatus of Electron, you should develop additional means for this check.\n\nExample\n\nEvent detection in the Renderer process\nStarting with a working application from the\nQuick Start Guide, update the main.js file\nwith the following lines:\nconst { app, BrowserWindow } = require('electron')\n\nlet onlineStatusWindow\n\napp.whenReady().then(() => {\n onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false })\n onlineStatusWindow.loadURL(`file://${__dirname}/index.html`)\n})\n\nin the index.html file, add the following line before the\nclosing </body> tag:\n<script src=\"renderer.js\"></script>\n\nand add the renderer.js file:\nconst alertOnlineStatus = () => { window.alert(navigator.onLine ? 'online' : 'offline') }\n\nwindow.addEventListener('online', alertOnlineStatus)\nwindow.addEventListener('offline', alertOnlineStatus)\n\nalertOnlineStatus()\n\nAfter launching the Electron application, you should see the notification:\n\n\nEvent detection in the Main process\nThere may be situations when you want to respond to online/offline events in\nthe Main process as well. The Main process, however, does not have a\nnavigator object and cannot detect these events directly. In this case, you\nneed to forward the events to the Main process using Electron's inter-process\ncommunication (IPC) utilities.\nStarting with a working application from the\nQuick Start Guide, update the main.js file\nwith the following lines:\nconst { app, BrowserWindow, ipcMain } = require('electron')\nlet onlineStatusWindow\n\napp.whenReady().then(() => {\n onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false, webPreferences: { nodeIntegration: true } })\n onlineStatusWindow.loadURL(`file://${__dirname}/index.html`)\n})\n\nipcMain.on('online-status-changed', (event, status) => {\n console.log(status)\n})\n\nin the index.html file, add the following line before the\nclosing </body> tag:\n<script src=\"renderer.js\"></script>\n\nand add the renderer.js file:\nconst { ipcRenderer } = require('electron')\nconst updateOnlineStatus = () => { ipcRenderer.send('online-status-changed', navigator.onLine ? 'online' : 'offline') }\n\nwindow.addEventListener('online', updateOnlineStatus)\nwindow.addEventListener('offline', updateOnlineStatus)\n\nupdateOnlineStatus()\n\nAfter launching the Electron application, you should see the notification in the\nConsole:\nnpm start\n\n> electron@1.0.0 start /electron\n> electron .\n\nonline\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Online/Offline Event Detection",
"doc:online-offline-events",
"tutorial:Online/Offline Event Detection",
"tutorial:online-offline-events"
]
},
{
"objectID": "tutorial-patches",
"title": "Patches in Electron",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/development/patches.md",
"url": "https://electronjs.org/docs/development/patches",
"slug": "patches",
"body": "Patches in Electron\nElectron is built on two major upstream projects: Chromium and Node.js. Each of these projects has several of their own dependencies, too. We try our best to use these dependencies exactly as they are but sometimes we can't achieve our goals without patching those upstream dependencies to fit our use cases.\n\nPatch justification\nEvery patch in Electron is a maintenance burden. When upstream code changes, patches can break—sometimes without even a patch conflict or a compilation error. It's an ongoing effort to keep our patch set up-to-date and effective. So we strive to keep our patch count at a minimum. To that end, every patch must describe its reason for existence in its commit message. That reason must be one of the following:\n\nThe patch is temporary, and is intended to be (or has been) committed upstream or otherwise eventually removed. Include a link to an upstream PR or code review if available, or a procedure for verifying whether the patch is still needed at a later date.\nThe patch allows the code to compile in the Electron environment, but cannot be upstreamed because it's Electron-specific (e.g. patching out references to Chrome's Profile). Include reasoning about why the change cannot be implemented without a patch (e.g. by subclassing or copying the code).\nThe patch makes Electron-specific changes in functionality which are fundamentally incompatible with upstream.\n\nIn general, all the upstream projects we work with are friendly folks and are often happy to accept refactorings that allow the code in question to be compatible with both Electron and the upstream project. (See e.g. this change in Chromium, which allowed us to remove a patch that did the same thing, or this change in Node, which was a no-op for Node but fixed a bug in Electron.) We should aim to upstream changes whenever we can, and avoid indefinite-lifetime patches.\n\nPatch system\nIf you find yourself in the unfortunate position of having to make a change which can only be made through patching an upstream project, you'll need to know how to manage patches in Electron.\nAll patches to upstream projects in Electron are contained in the patches/ directory. Each subdirectory of patches/ contains several patch files, along with a .patches file which lists the order in which the patches should be applied. Think of these files as making up a series of git commits that are applied on top of the upstream project after we check it out.\npatches\n├── config.json <-- this describes which patchset directory is applied to what project\n├── chromium\n│   ├── .patches\n│   ├── accelerator.patch\n│   ├── add_contentgpuclient_precreatemessageloop_callback.patch\n│ ⋮\n├── node\n│   ├── .patches\n│   ├── add_openssl_is_boringssl_guard_to_oaep_hash_check.patch\n│   ├── build_add_gn_build_files.patch\n│   ⋮\n⋮\n\nTo help manage these patch sets, we provide two tools: git-import-patches and git-export-patches. git-import-patches imports a set of patch files into a git repository by applying each patch in the correct order and creating a commit for each one. git-export-patches does the reverse; it exports a series of git commits in a repository into a set of files in a directory and an accompanying .patches file.\n\nSide note: the reason we use a .patches file to maintain the order of applied patches, rather than prepending a number like 001- to each file, is because it reduces conflicts related to patch ordering. It prevents the situation where two PRs both add a patch at the end of the series with the same numbering and end up both getting merged resulting in a duplicate identifier, and it also reduces churn when a patch is added or deleted in the middle of the series.\n\n\nUsage\n\nAdding a new patch\n$ cd src/third_party/electron_node\n$ vim some/code/file.cc\n$ git commit\n$ ../../electron/script/git-export-patches -o ../../electron/patches/node\n\n\nNOTE: git-export-patches ignores any uncommitted files, so you must create a commit if you want your changes to be exported. The subject line of the commit message will be used to derive the patch file name, and the body of the commit message should include the reason for the patch's existence.\n\nRe-exporting patches will sometimes cause shasums in unrelated patches to change. This is generally harmless and can be ignored (but go ahead and add those changes to your PR, it'll stop them from showing up for other people).\n\nEditing an existing patch\n$ cd src/v8\n$ vim some/code/file.cc\n$ git log\n# Find the commit sha of the patch you want to edit.\n$ git commit --fixup [COMMIT_SHA]\n$ git rebase --autosquash -i [COMMIT_SHA]^\n$ ../electron/script/git-export-patches -o ../electron/patches/v8\n\n\nRemoving a patch\n$ vim src/electron/patches/node/.patches\n# Delete the line with the name of the patch you want to remove\n$ cd src/third_party/electron_node\n$ git reset --hard refs/patches/upstream-head\n$ ../../electron/script/git-import-patches ../../electron/patches/node\n$ ../../electron/script/git-export-patches -o ../../electron/patches/node\n\nNote that git-import-patches will mark the commit that was HEAD when it was run as refs/patches/upstream-head. This lets you keep track of which commits are from Electron patches (those that come after refs/patches/upstream-head) and which commits are in upstream (those before refs/patches/upstream-head).\n\nResolving conflicts\nWhen updating an upstream dependency, patches may fail to apply cleanly. Often, the conflict can be resolved automatically by git with a 3-way merge. You can instruct git-import-patches to use the 3-way merge algorithm by passing the -3 argument:\n$ cd src/third_party/electron_node\n# If the patch application failed midway through, you can reset it with:\n$ git am --abort\n# And then retry with 3-way merge:\n$ ../../electron/script/git-import-patches -3 ../../electron/patches/node\n\nIf git-import-patches -3 encounters a merge conflict that it can't resolve automatically, it will pause and allow you to resolve the conflict manually. Once you have resolved the conflict, git add the resolved files and continue to apply the rest of the patches by running git am --continue.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Patches in Electron",
"doc:patches",
"tutorial:Patches in Electron",
"tutorial:patches"
]
},
{
"objectID": "tutorial-performance",
"title": "Performance",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/performance.md",
"url": "https://electronjs.org/docs/tutorial/performance",
"slug": "performance",
"body": "Performance\nDevelopers frequently ask about strategies to optimize the performance of\nElectron applications. Software engineers, consumers, and framework developers\ndo not always agree on one single definition of what \"performance\" means. This\ndocument outlines some of the Electron maintainers' favorite ways to reduce the\namount of memory, CPU, and disk resources being used while ensuring that your\napp is responsive to user input and completes operations as quickly as\npossible. Furthermore, we want all performance strategies to maintain a high\nstandard for your app's security.\nWisdom and information about how to build performant websites with JavaScript\ngenerally applies to Electron apps, too. To a certain extent, resources\ndiscussing how to build performant Node.js applications also apply, but be\ncareful to understand that the term \"performance\" means different things for\na Node.js backend than it does for an application running on a client.\nThis list is provided for your convenience – and is, much like our\nsecurity checklist – not meant to exhaustive. It is probably possible\nto build a slow Electron app that follows all the steps outlined below. Electron\nis a powerful development platform that enables you, the developer, to do more\nor less whatever you want. All that freedom means that performance is largely\nyour responsibility.\n\nMeasure, Measure, Measure\nThe list below contains a number of steps that are fairly straightforward and\neasy to implement. However, building the most performant version of your app\nwill require you to go beyond a number of steps. Instead, you will have to\nclosely examine all the code running in your app by carefully profiling and\nmeasuring. Where are the bottlenecks? When the user clicks a button, what\noperations take up the brunt of the time? While the app is simply idling, which\nobjects take up the most memory?\nTime and time again, we have seen that the most successful strategy for building\na performant Electron app is to profile the running code, find the most\nresource-hungry piece of it, and to optimize it. Repeating this seemingly\nlaborious process over and over again will dramatically increase your app's\nperformance. Experience from working with major apps like Visual Studio Code or\nSlack has shown that this practice is by far the most reliable strategy to\nimprove performance.\nTo learn more about how to profile your app's code, familiarize yourself with\nthe Chrome Developer Tools. For advanced analysis looking at multiple processes\nat once, consider the Chrome Tracing tool.\n\nRecommended Reading\n\nGet Started With Analyzing Runtime Performance\nTalk: \"Visual Studio Code - The First Second\"\n\n\nChecklist\nChances are that your app could be a little leaner, faster, and generally less\nresource-hungry if you attempt these steps.\n\nCarelessly including modules\nLoading and running code too soon\nBlocking the main process\nBlocking the renderer process\nUnnecessary polyfills\nUnnecessary or blocking network requests\nBundle your code\n\n\n1) Carelessly including modules\nBefore adding a Node.js module to your application, examine said module. How\nmany dependencies does that module include? What kind of resources does\nit need to simply be called in a require() statement? You might find\nthat the module with the most downloads on the NPM package registry or the most stars on GitHub\nis not in fact the leanest or smallest one available.\n\nWhy?\nThe reasoning behind this recommendation is best illustrated with a real-world\nexample. During the early days of Electron, reliable detection of network\nconnectivity was a problem, resulting many apps to use a module that exposed a\nsimple isOnline() method.\nThat module detected your network connectivity by attempting to reach out to a\nnumber of well-known endpoints. For the list of those endpoints, it depended on\na different module, which also contained a list of well-known ports. This\ndependency itself relied on a module containing information about ports, which\ncame in the form of a JSON file with more than 100,000 lines of content.\nWhenever the module was loaded (usually in a require('module') statement),\nit would load all its dependencies and eventually read and parse this JSON\nfile. Parsing many thousands lines of JSON is a very expensive operation. On\na slow machine it can take up whole seconds of time.\nIn many server contexts, startup time is virtually irrelevant. A Node.js server\nthat requires information about all ports is likely actually \"more performant\"\nif it loads all required information into memory whenever the server boots at\nthe benefit of serving requests faster. The module discussed in this example is\nnot a \"bad\" module. Electron apps, however, should not be loading, parsing, and\nstoring in memory information that it does not actually need.\nIn short, a seemingly excellent module written primarily for Node.js servers\nrunning Linux might be bad news for your app's performance. In this particular\nexample, the correct solution was to use no module at all, and to instead use\nconnectivity checks included in later versions of Chromium.\n\nHow?\nWhen considering a module, we recommend that you check:\n\nthe size of dependencies included\nthe resources required to load (require()) it\nthe resources required to perform the action you're interested in\n\nGenerating a CPU profile and a heap memory profile for loading a module can be done\nwith a single command on the command line. In the example below, we're looking at\nthe popular module request.\nnode --cpu-prof --heap-prof -e \"require('request')\"\n\nExecuting this command results in a .cpuprofile file and a .heapprofile\nfile in the directory you executed it in. Both files can be analyzed using\nthe Chrome Developer Tools, using the Performance and Memory tabs\nrespectively.\n\n\nIn this example, on the author's machine, we saw that loading request took\nalmost half a second, whereas node-fetch took dramatically less memory\nand less than 50ms.\n\n2) Loading and running code too soon\nIf you have expensive setup operations, consider deferring those. Inspect all\nthe work being executed right after the application starts. Instead of firing\noff all operations right away, consider staggering them in a sequence more\nclosely aligned with the user's journey.\nIn traditional Node.js development, we're used to putting all our require()\nstatements at the top. If you're currently writing your Electron application\nusing the same strategy and are using sizable modules that you do not\nimmediately need, apply the same strategy and defer loading to a more\nopportune time.\n\nWhy?\nLoading modules is a surprisingly expensive operation, especially on Windows.\nWhen your app starts, it should not make users wait for operations that are\ncurrently not necessary.\nThis might seem obvious, but many applications tend to do a large amount of\nwork immediately after the app has launched - like checking for updates,\ndownloading content used in a later flow, or performing heavy disk I/O\noperations.\nLet's consider Visual Studio Code as an example. When you open a file, it will\nimmediately display the file to you without any code highlighting, prioritizing\nyour ability to interact with the text. Once it has done that work, it will\nmove on to code highlighting.\n\nHow?\nLet's consider an example and assume that your application is parsing files\nin the fictitious .foo format. In order to do that, it relies on the\nequally fictitious foo-parser module. In traditional Node.js development,\nyou might write code that eagerly loads dependencies:\nconst fs = require('fs')\nconst fooParser = require('foo-parser')\n\nclass Parser {\n constructor () {\n this.files = fs.readdirSync('.')\n }\n\n getParsedFiles () {\n return fooParser.parse(this.files)\n }\n}\n\nconst parser = new Parser()\n\nmodule.exports = { parser }\n\nIn the above example, we're doing a lot of work that's being executed as soon\nas the file is loaded. Do we need to get parsed files right away? Could we\ndo this work a little later, when getParsedFiles() is actually called?\n// \"fs\" is likely already being loaded, so the `require()` call is cheap\nconst fs = require('fs')\n\nclass Parser {\n async getFiles () {\n // Touch the disk as soon as `getFiles` is called, not sooner.\n // Also, ensure that we're not blocking other operations by using\n // the asynchronous version.\n this.files = this.files || await fs.readdir('.')\n\n return this.files\n }\n\n async getParsedFiles () {\n // Our fictitious foo-parser is a big and expensive module to load, so\n // defer that work until we actually need to parse files.\n // Since `require()` comes with a module cache, the `require()` call\n // will only be expensive once - subsequent calls of `getParsedFiles()`\n // will be faster.\n const fooParser = require('foo-parser')\n const files = await this.getFiles()\n\n return fooParser.parse(files)\n }\n}\n\n// This operation is now a lot cheaper than in our previous example\nconst parser = new Parser()\n\nmodule.exports = { parser }\n\nIn short, allocate resources \"just in time\" rather than allocating them all\nwhen your app starts.\n\n3) Blocking the main process\nElectron's main process (sometimes called \"browser process\") is special: It is\nthe parent process to all your app's other processes and the primary process\nthe operating system interacts with. It handles windows, interactions, and the\ncommunication between various components inside your app. It also houses the\nUI thread.\nUnder no circumstances should you block this process and the UI thread with\nlong-running operations. Blocking the UI thread means that your entire app\nwill freeze until the main process is ready to continue processing.\n\nWhy?\nThe main process and its UI thread are essentially the control tower for major\noperations inside your app. When the operating system tells your app about a\nmouse click, it'll go through the main process before it reaches your window.\nIf your window is rendering a buttery-smooth animation, it'll need to talk to\nthe GPU process about that – once again going through the main process.\nElectron and Chromium are careful to put heavy disk I/O and CPU-bound operations\nonto new threads to avoid blocking the UI thread. You should do the same.\n\nHow?\nElectron's powerful multi-process architecture stands ready to assist you with\nyour long-running tasks, but also includes a small number of performance traps.\n1) For long running CPU-heavy tasks, make use of\nworker threads, consider moving them to the BrowserWindow, or\n(as a last resort) spawn a dedicated process.\n2) Avoid using the synchronous IPC and the remote module as much as possible.\nWhile there are legitimate use cases, it is far too easy to unknowingly block\nthe UI thread using the remote module.\n3) Avoid using blocking I/O operations in the main process. In short, whenever\ncore Node.js modules (like fs or child_process) offer a synchronous or an\nasynchronous version, you should prefer the asynchronous and non-blocking\nvariant.\n\n4) Blocking the renderer process\nSince Electron ships with a current version of Chrome, you can make use of the\nlatest and greatest features the Web Platform offers to defer or offload heavy\noperations in a way that keeps your app smooth and responsive.\n\nWhy?\nYour app probably has a lot of JavaScript to run in the renderer process. The\ntrick is to execute operations as quickly as possible without taking away\nresources needed to keep scrolling smooth, respond to user input, or animations\nat 60fps.\nOrchestrating the flow of operations in your renderer's code is\nparticularly useful if users complain about your app sometimes \"stuttering\".\n\nHow?\nGenerally speaking, all advice for building performant web apps for modern\nbrowsers apply to Electron's renderers, too. The two primary tools at your\ndisposal are currently requestIdleCallback() for small operations and\nWeb Workers for long-running operations.\nrequestIdleCallback() allows developers to queue up a function to be\nexecuted as soon as the process is entering an idle period. It enables you to\nperform low-priority or background work without impacting the user experience.\nFor more information about how to use it,\ncheck out its documentation on MDN.\nWeb Workers are a powerful tool to run code on a separate thread. There are\nsome caveats to consider – consult Electron's\nmultithreading documentation and the\nMDN documentation for Web Workers. They're an ideal solution\nfor any operation that requires a lot of CPU power for an extended period of\ntime.\n\n5) Unnecessary polyfills\nOne of Electron's great benefits is that you know exactly which engine will\nparse your JavaScript, HTML, and CSS. If you're re-purposing code that was\nwritten for the web at large, make sure to not polyfill features included in\nElectron.\n\nWhy?\nWhen building a web application for today's Internet, the oldest environments\ndictate what features you can and cannot use. Even though Electron supports\nwell-performing CSS filters and animations, an older browser might not. Where\nyou could use WebGL, your developers may have chosen a more resource-hungry\nsolution to support older phones.\nWhen it comes to JavaScript, you may have included toolkit libraries like\njQuery for DOM selectors or polyfills like the regenerator-runtime to support\nasync/await.\nIt is rare for a JavaScript-based polyfill to be faster than the equivalent\nnative feature in Electron. Do not slow down your Electron app by shipping your\nown version of standard web platform features.\n\nHow?\nOperate under the assumption that polyfills in current versions of Electron\nare unnecessary. If you have doubts, check caniuse.com\nand check if the version of Chromium used in your Electron version\nsupports the feature you desire.\nIn addition, carefully examine the libraries you use. Are they really necessary?\njQuery, for example, was such a success that many of its features are now part\nof the standard JavaScript feature set available.\nIf you're using a transpiler/compiler like TypeScript, examine its configuration\nand ensure that you're targeting the latest ECMAScript version supported by\nElectron.\n\n6) Unnecessary or blocking network requests\nAvoid fetching rarely changing resources from the internet if they could easily\nbe bundled with your application.\n\nWhy?\nMany users of Electron start with an entirely web-based app that they're\nturning into a desktop application. As web developers, we are used to loading\nresources from a variety of content delivery networks. Now that you are\nshipping a proper desktop application, attempt to \"cut the cord\" where possible\nand avoid letting your users wait for resources that never change and could\neasily be included in your app.\nA typical example is Google Fonts. Many developers make use of Google's\nimpressive collection of free fonts, which comes with a content delivery\nnetwork. The pitch is straightforward: Include a few lines of CSS and Google\nwill take care of the rest.\nWhen building an Electron app, your users are better served if you download\nthe fonts and include them in your app's bundle.\n\nHow?\nIn an ideal world, your application wouldn't need the network to operate at\nall. To get there, you must understand what resources your app is downloading\n- and how large those resources are.\nTo do so, open up the developer tools. Navigate to the Network tab and check\nthe Disable cache option. Then, reload your renderer. Unless your app\nprohibits such reloads, you can usually trigger a reload by hitting Cmd + R\nor Ctrl + R with the developer tools in focus.\nThe tools will now meticulously record all network requests. In a first pass,\ntake stock of all the resources being downloaded, focusing on the larger files\nfirst. Are any of them images, fonts, or media files that don't change and\ncould be included with your bundle? If so, include them.\nAs a next step, enable Network Throttling. Find the drop-down that currently\nreads Online and select a slower speed such as Fast 3G. Reload your\nrenderer and see if there are any resources that your app is unnecessarily\nwaiting for. In many cases, an app will wait for a network request to complete\ndespite not actually needing the involved resource.\nAs a tip, loading resources from the Internet that you might want to change\nwithout shipping an application update is a powerful strategy. For advanced\ncontrol over how resources are being loaded, consider investing in\nService Workers.\n\n7) Bundle your code\nAs already pointed out in\n\"Loading and running code too soon\",\ncalling require() is an expensive operation. If you are able to do so,\nbundle your application's code into a single file.\n\nWhy?\nModern JavaScript development usually involves many files and modules. While\nthat's perfectly fine for developing with Electron, we heavily recommend that\nyou bundle all your code into one single file to ensure that the overhead\nincluded in calling require() is only paid once when your application loads.\n\nHow?\nThere are numerous JavaScript bundlers out there and we know better than to\nanger the community by recommending one tool over another. We do however\nrecommend that you use a bundler that is able to handle Electron's unique\nenvironment that needs to handle both Node.js and browser environments.\nAs of writing this article, the popular choices include Webpack,\nParcel, and rollup.js.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Performance",
"doc:performance",
"tutorial:Performance",
"tutorial:performance"
]
},
{
"objectID": "tutorial-progress-bar",
"title": "Progress Bar in Taskbar (Windows, macOS, Unity)",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/progress-bar.md",
"url": "https://electronjs.org/docs/tutorial/progress-bar",
"slug": "progress-bar",
"body": "Progress Bar in Taskbar (Windows, macOS, Unity)\n\nOverview\nA progress bar enables a window to provide progress information to the user\nwithout the need of switching to the window itself.\nOn Windows, you can use a taskbar button to display a progress bar.\n\nOn macOS, the progress bar will be displayed as a part of the dock icon.\n\nOn Linux, the Unity graphical interface also has a similar feature that allows\nyou to specify the progress bar in the launcher.\n\n\nNOTE: on Windows, each window can have its own progress bar, whereas on macOS\nand Linux (Unity) there can be only one progress bar for the application.\n\n\nAll three cases are covered by the same API - the\nsetProgressBar() method available on an instance of\nBrowserWindow. To indicate your progress, call this method with a number\nbetween 0 and 1. For example, if you have a long-running task that is\ncurrently at 63% towards completion, you would call it as\nsetProgressBar(0.63).\nSetting the parameter to negative values (e.g. -1) will remove the progress\nbar, whereas setting it to values greater than 1 (e.g. 2) will switch the\nprogress bar to indeterminate mode (Windows-only -- it will clamp to 100%\notherwise). In this mode, a progress bar remains active but does not show an\nactual percentage. Use this mode for situations when you do not know how long\nan operation will take to complete.\nSee the API documentation for more options and modes.\n\nExample\nStarting with a working application from the\nQuick Start Guide, add the following lines to the\nmain.js file:\nconst { BrowserWindow } = require('electron')\nconst win = new BrowserWindow()\n\nwin.setProgressBar(0.5)\n\nAfter launching the Electron application, you should see the bar in\nthe dock (macOS) or taskbar (Windows, Unity), indicating the progress\npercentage you just defined.\n\nFor macOS, the progress bar will also be indicated for your application\nwhen using Mission Control:\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Progress Bar in Taskbar (Windows, macOS, Unity)",
"doc:progress-bar",
"tutorial:Progress Bar in Taskbar (Windows, macOS, Unity)",
"tutorial:progress-bar"
]
},
{
"objectID": "tutorial-pull-requests",
"title": "Pull Requests",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/development/pull-requests.md",
"url": "https://electronjs.org/docs/development/pull-requests",
"slug": "pull-requests",
"body": "Pull Requests\n\nSetting up your local environment\nStep 1: Fork\nStep 2: Build\nStep 3: Branch\n\nMaking Changes\nStep 4: Code\nStep 5: Commit\nCommit message guidelines\n\nStep 6: Rebase\nStep 7: Test\nStep 8: Push\nStep 9: Opening the Pull Request\nStep 10: Discuss and Update\nApproval and Request Changes Workflow\n\nStep 11: Landing\nContinuous Integration Testing\n\n\n\nSetting up your local environment\n\nStep 1: Fork\nFork the project on GitHub and clone your fork\nlocally.\n$ git clone git@github.com:username/electron.git\n$ cd electron\n$ git remote add upstream https://github.com/electron/electron.git\n$ git fetch upstream\n\n\nStep 2: Build\nBuild steps and dependencies differ slightly depending on your operating system.\nSee these detailed guides on building Electron locally:\n\nBuilding on macOS\nBuilding on Linux\nBuilding on Windows\n\nOnce you've built the project locally, you're ready to start making changes!\n\nStep 3: Branch\nTo keep your development environment organized, create local branches to\nhold your work. These should be branched directly off of the master branch.\n$ git checkout -b my-branch -t upstream/master\n\n\nMaking Changes\n\nStep 4: Code\nMost pull requests opened against the electron/electron repository include\nchanges to either the C/C++ code in the shell/ folder,\nthe JavaScript code in the lib/ folder, the documentation in docs/api/\nor tests in the spec/ folder.\nPlease be sure to run npm run lint from time to time on any code changes\nto ensure that they follow the project's code style.\nSee coding style for\nmore information about best practice when modifying code in different parts of\nthe project.\n\nStep 5: Commit\nIt is recommended to keep your changes grouped logically within individual\ncommits. Many contributors find it easier to review changes that are split\nacross multiple commits. There is no limit to the number of commits in a\npull request.\n$ git add my/changed/files\n$ git commit\n\nNote that multiple commits often get squashed when they are landed.\n\nCommit message guidelines\nA good commit message should describe what changed and why. The Electron project\nuses semantic commit messages to streamline\nthe release process.\nBefore a pull request can be merged, it must have a pull request title with a semantic prefix.\nExamples of commit messages with semantic prefixes:\n\nfix: don't overwrite prevent_default if default wasn't prevented\nfeat: add app.isPackaged() method\ndocs: app.isDefaultProtocolClient is now available on Linux\n\nCommon prefixes:\n\nfix: A bug fix\nfeat: A new feature\ndocs: Documentation changes\ntest: Adding missing tests or correcting existing tests\nbuild: Changes that affect the build system\nci: Changes to our CI configuration files and scripts\nperf: A code change that improves performance\nrefactor: A code change that neither fixes a bug nor adds a feature\nstyle: Changes that do not affect the meaning of the code (linting)\nvendor: Bumping a dependency like libchromiumcontent or node\n\nOther things to keep in mind when writing a commit message:\n\nThe first line should:\ncontain a short description of the change (preferably 50 characters or less,\nand no more than 72 characters)\nbe entirely in lowercase with the exception of proper nouns, acronyms, and\nthe words that refer to code, like function/variable names\n\nKeep the second line blank.\nWrap all other lines at 72 columns.\n\n\nBreaking Changes\nA commit that has the text BREAKING CHANGE: at the beginning of its optional\nbody or footer section introduces a breaking API change (correlating with Major\nin semantic versioning). A breaking change can be part of commits of any type.\ne.g., a fix:, feat: & chore: types would all be valid, in addition to any\nother type.\nSee conventionalcommits.org for more details.\n\nStep 6: Rebase\nOnce you have committed your changes, it is a good idea to use git rebase\n(not git merge) to synchronize your work with the main repository.\n$ git fetch upstream\n$ git rebase upstream/master\n\nThis ensures that your working branch has the latest changes from electron/electron\nmaster.\n\nStep 7: Test\nBug fixes and features should always come with tests. A\ntesting guide has been\nprovided to make the process easier. Looking at other tests to see how they\nshould be structured can also help.\nBefore submitting your changes in a pull request, always run the full\ntest suite. To run the tests:\n$ npm run test\n\nMake sure the linter does not report any issues and that all tests pass.\nPlease do not submit patches that fail either check.\nIf you are updating tests and want to run a single spec to check it:\n$ npm run test -match=menu\n\nThe above would only run spec modules matching menu, which is useful for\nanyone who's working on tests that would otherwise be at the very end of\nthe testing cycle.\n\nStep 8: Push\nOnce your commits are ready to go -- with passing tests and linting --\nbegin the process of opening a pull request by pushing your working branch\nto your fork on GitHub.\n$ git push origin my-branch\n\n\nStep 9: Opening the Pull Request\nFrom within GitHub, opening a new pull request will present you with a template\nthat should be filled out:\n<!--\nThank you for your pull request. Please provide a description above and review\nthe requirements below.\n\nBug fixes and new features should include tests and possibly benchmarks.\n\nContributors guide: https://github.com/electron/electron/blob/master/CONTRIBUTING.md\n-->\n\n\nStep 10: Discuss and update\nYou will probably get feedback or requests for changes to your pull request.\nThis is a big part of the submission process so don't be discouraged! Some\ncontributors may sign off on the pull request right away. Others may have\ndetailed comments or feedback. This is a necessary part of the process\nin order to evaluate whether the changes are correct and necessary.\nTo make changes to an existing pull request, make the changes to your local\nbranch, add a new commit with those changes, and push those to your fork.\nGitHub will automatically update the pull request.\n$ git add my/changed/files\n$ git commit\n$ git push origin my-branch\n\nThere are a number of more advanced mechanisms for managing commits using\ngit rebase that can be used, but are beyond the scope of this guide.\nFeel free to post a comment in the pull request to ping reviewers if you are\nawaiting an answer on something. If you encounter words or acronyms that\nseem unfamiliar, refer to this\nglossary.\n\nApproval and Request Changes Workflow\nAll pull requests require approval from a\nCode Owner\nof the area you modified in order to land. Whenever a maintainer reviews a pull\nrequest they may request changes. These may be small, such as fixing a typo, or\nmay involve substantive changes. Such requests are intended to be helpful, but\nat times may come across as abrupt or unhelpful, especially if they do not include\nconcrete suggestions on how to change them.\nTry not to be discouraged. If you feel that a review is unfair, say so or seek\nthe input of another project contributor. Often such comments are the result of\na reviewer having taken insufficient time to review and are not ill-intended.\nSuch difficulties can often be resolved with a bit of patience. That said,\nreviewers should be expected to provide helpful feedback.\n\nStep 11: Landing\nIn order to land, a pull request needs to be reviewed and approved by\nat least one Electron Code Owner and pass CI. After that, if there are no\nobjections from other contributors, the pull request can be merged.\nCongratulations and thanks for your contribution!\n\nContinuous Integration Testing\nEvery pull request is tested on the Continuous Integration (CI) system to\nconfirm that it works on Electron's supported platforms.\nIdeally, the pull request will pass (\"be green\") on all of CI's platforms.\nThis means that all tests pass and there are no linting errors. However,\nit is not uncommon for the CI infrastructure itself to fail on specific\nplatforms or for so-called \"flaky\" tests to fail (\"be red\"). Each CI\nfailure must be manually inspected to determine the cause.\nCI starts automatically when you open a pull request, but only\ncore maintainers can restart a CI run. If you believe CI is giving a\nfalse negative, ask a maintainer to restart the tests.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Pull Requests",
"doc:pull-requests",
"tutorial:Pull Requests",
"tutorial:pull-requests"
]
},
{
"objectID": "tutorial-quick-start",
"title": "Quick Start Guide",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/quick-start.md",
"url": "https://electronjs.org/docs/tutorial/quick-start",
"slug": "quick-start",
"body": "Quick Start Guide\n\nQuickstart\nElectron is a framework that enables you to create desktop applications with JavaScript, HTML, and CSS. These applications can then be packaged to run directly on macOS, Windows, or Linux, or distributed via the Mac App Store or the Microsoft Store.\nTypically, you create a desktop application for an operating system (OS) using each operating system's specific native application frameworks. Electron makes it possible to write your application once using technologies that you already know.\n\nPrerequisites\nBefore proceeding with Electron you need to install Node.js.\nWe recommend that you install either the latest LTS or Current version available.\n\nPlease install Node.js using pre-built installers for your platform.\nYou may encounter incompatibility issues with different development tools otherwise.\n\nTo check that Node.js was installed correctly, type the following commands in your terminal client:\nnode -v\nnpm -v\n\nThe commands should print the versions of Node.js and npm accordingly.\nIf both commands succeeded, you are ready to install Electron.\n\nCreate a basic application\nFrom a development perspective, an Electron application is essentially a Node.js application. This means that the starting point of your Electron application will be a package.json file like in any other Node.js application. A minimal Electron application has the following structure:\nmy-electron-app/\n├── package.json\n├── main.js\n├── preload.js\n└── index.html\n\nLet's create a basic application based on the structure above.\n\nInstall Electron\nCreate a folder for your project and install Electron there:\nmkdir my-electron-app && cd my-electron-app\nnpm init -y\nnpm i --save-dev electron\n\n\nCreate the main script file\nThe main script specifies the entry point of your Electron application (in our case, the main.js file) that will run the Main process. Typically, the script that runs in the Main process controls the lifecycle of the application, displays the graphical user interface and its elements, performs native operating system interactions, and creates Renderer processes within web pages. An Electron application can have only one Main process.\nThe main script may look as follows:\nconst { app, BrowserWindow } = require('electron')\nconst path = require('path')\n\nfunction createWindow () {\n const win = new BrowserWindow({\n width: 800,\n height: 600,\n webPreferences: {\n preload: path.join(__dirname, 'preload.js')\n }\n })\n\n win.loadFile('index.html')\n}\n\napp.whenReady().then(() => {\n createWindow()\n\n app.on('activate', () => {\n if (BrowserWindow.getAllWindows().length === 0) {\n createWindow()\n }\n })\n})\n\napp.on('window-all-closed', () => {\n if (process.platform !== 'darwin') {\n app.quit()\n }\n})\n\n\nWhat is going on above?\n\nLine 1: First, you import the app and BrowserWindow modules of the electron package to be able to manage your application's lifecycle events, as well as create and control browser windows.\nLine 2: Second, you import the path package which provides utility functions for file paths.\nLine 4: After that, you define a function that creates a new browser window with a preload script, loads index.html file into this window (line 13, we will discuss the file later).\nLine 16: You create a new browser window by invoking the createWindow function once the Electron application is initialized.\nLine 18: You add a new listener that creates a new browser window only if when the application has no visible windows after being activated. For example, after launching the application for the first time, or re-launching the already running application.\nLine 25: You add a new listener that tries to quit the application when it no longer has any open windows. This listener is a no-op on macOS due to the operating system's window management behavior.\n\n\nCreate a web page\nThis is the web page you want to display once the application is initialized. This web page represents the Renderer process. You can create multiple browser windows, where each window uses its own independent Renderer. You can optionally grant access to additional Node.js APIs by exposing them from your preload script.\nThe index.html page looks as follows:\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"UTF-8\">\n <title>Hello World!</title>\n <meta http-equiv=\"Content-Security-Policy\" content=\"script-src 'self' 'unsafe-inline';\" />\n</head>\n<body style=\"background: white;\">\n <h1>Hello World!</h1>\n <p>\n We are using Node.js <span id=\"node-version\"></span>,\n Chromium <span id=\"chrome-version\"></span>,\n and Electron <span id=\"electron-version\"></span>.\n </p>\n</body>\n</html>\n\n\nDefine a preload script\nYour preload script acts as a bridge between Node.js and your web page. It allows you to expose specific APIs and behaviors to your web page rather than insecurely exposing the entire Node.js API. In this example we will use the preload script to read version information from the process object and update the web page with that info.\nwindow.addEventListener('DOMContentLoaded', () => {\n const replaceText = (selector, text) => {\n const element = document.getElementById(selector)\n if (element) element.innerText = text\n }\n\n for (const type of ['chrome', 'node', 'electron']) {\n replaceText(`${type}-version`, process.versions[type])\n }\n})\n\n\nWhat's going on above?\n\nOn line 1: First you define an event listener that tells you when the web page has loaded\nOn line 2: Second you define a utility function used to set the text of the placeholders in the index.html\nOn line 7: Next you loop through the list of components whose version you want to display\nOn line 8: Finally, you call replaceText to look up the version placeholders in index.html and set their text value to the values from process.versions\n\n\nModify your package.json file\nYour Electron application uses the package.json file as the main entry point (as any other Node.js application). The main script of your application is main.js, so modify the package.json file accordingly:\n{\n \"name\": \"my-electron-app\",\n \"version\": \"0.1.0\",\n \"author\": \"your name\",\n \"description\": \"My Electron app\",\n \"main\": \"main.js\"\n}\n\n\nNOTE: If the main field is omitted, Electron will attempt to load an index.js file from the directory containing package.json.\n\n\nNOTE: The author and description fields are required for packaging, otherwise error will occur when running npm run make.\n\nBy default, the npm start command will run the main script with Node.js. To run the script with Electron, you need to change it as such:\n{\n \"name\": \"my-electron-app\",\n \"version\": \"0.1.0\",\n \"author\": \"your name\",\n \"description\": \"My Electron app\",\n \"main\": \"main.js\",\n \"scripts\": {\n \"start\": \"electron .\"\n }\n}\n\n\nRun your application\nnpm start\n\nYour running Electron app should look as follows:\n\n\nPackage and distribute the application\nThe simplest and the fastest way to distribute your newly created app is using\nElectron Forge.\n\n\nImport Electron Forge to your app folder:\nnpm install --save-dev @electron-forge/cli\nnpx electron-forge import\n\n✔ Checking your system\n✔ Initializing Git Repository\n✔ Writing modified package.json file\n✔ Installing dependencies\n✔ Writing modified package.json file\n✔ Fixing .gitignore\n\nWe have ATTEMPTED to convert your app to be in a format that electron-forge understands.\n\nThanks for using \"electron-forge\"!!!\n\n\n\nCreate a distributable:\nnpm run make\n\n> my-gsod-electron-app@1.0.0 make /my-electron-app\n> electron-forge make\n\n✔ Checking your system\n✔ Resolving Forge Config\nWe need to package your application before we can make it\n✔ Preparing to Package Application for arch: x64\n✔ Preparing native dependencies\n✔ Packaging Application\nMaking for the following targets: zip\n✔ Making for target: zip - On platform: darwin - For arch: x64\n\nElectron-forge creates the out folder where your package will be located:\n// Example for MacOS\nout/\n├── out/make/zip/darwin/x64/my-electron-app-darwin-x64-1.0.0.zip\n├── ...\n└── out/my-electron-app-darwin-x64/my-electron-app.app/Contents/MacOS/my-electron-app\n\n\n\n\nLearning the basics\nThis section guides you through the basics of how Electron works under the hood. It aims at strengthening knowledge about Electron and the application created earlier in the Quickstart section.\n\nApplication architecture\nElectron consists of three main pillars:\n\nChromium for displaying web content.\nNode.js for working with the local filesystem and the operating system.\nCustom APIs for working with often-needed OS native functions.\n\nDeveloping an application with Electron is like building a Node.js app with a web interface or building web pages with seamless Node.js integration.\n\nMain and Renderer Processes\nAs it was mentioned before, Electron has two types of processes: Main and Renderer.\n\nThe Main process creates web pages by creating BrowserWindow instances. Each BrowserWindow instance runs the web page in its Renderer process. When a BrowserWindow instance is destroyed, the corresponding Renderer process gets terminated as well.\nThe Main process manages all web pages and their corresponding Renderer processes.\n\n\n\nThe Renderer process manages only the corresponding web page. A crash in one Renderer process does not affect other Renderer processes.\nThe Renderer process communicates with the Main process via IPC to perform GUI operations in a web page. Calling native GUI-related APIs from the Renderer process directly is restricted due to security concerns and potential resource leakage.\n\n\nThe communication between processes is possible via Inter-Process Communication (IPC) modules: ipcMain and ipcRenderer.\n\nAPIs\n\nElectron API\nElectron APIs are assigned based on the process type, meaning that some modules can be used from either the Main or Renderer process, and some from both. Electron's API documentation indicates which process each module can be used from.\nFor example, to access the Electron API in both processes, require its included module:\nconst electron = require('electron')\n\nTo create a window, call the BrowserWindow class, which is only available in the Main process:\nconst { BrowserWindow } = require('electron')\nconst win = new BrowserWindow()\n\nTo call the Main process from the Renderer, use the IPC module:\n// In the Main process\nconst { ipcMain } = require('electron')\n\nipcMain.handle('perform-action', (event, ...args) => {\n // ... do actions on behalf of the Renderer\n})\n\n// In the Renderer process\nconst { ipcRenderer } = require('electron')\n\nipcRenderer.invoke('perform-action', ...args)\n\n\nNOTE: Because Renderer processes may run untrusted code (especially from third parties), it is important to carefully validate the requests that come to the Main process.\n\n\nNode.js API\n\nNOTE: To access the Node.js API from the Renderer process, you need to set the nodeIntegration preference to true and the contextIsolation preference to false. Please note that access to the Node.js API in any renderer that loads remote content is not recommended for security reasons.\n\nElectron exposes full access to Node.js API and its modules both in the Main and the Renderer processes. For example, you can read all the files from the root directory:\nconst fs = require('fs')\n\nconst root = fs.readdirSync('/')\n\nconsole.log(root)\n\nTo use a Node.js module, you first need to install it as a dependency:\nnpm install --save aws-sdk\n\nThen, in your Electron application, require the module:\nconst S3 = require('aws-sdk/clients/s3')\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Quick Start Guide",
"doc:quick-start",
"tutorial:Quick Start Guide",
"tutorial:quick-start"
]
},
{
"objectID": "tutorial-recent-documents",
"title": "Recent Documents (Windows & macOS)",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/recent-documents.md",
"url": "https://electronjs.org/docs/tutorial/recent-documents",
"slug": "recent-documents",
"body": "Recent Documents (Windows & macOS)\n\nOverview\nWindows and macOS provide access to a list of recent documents opened by\nthe application via JumpList or dock menu, respectively.\nJumpList:\n\nApplication dock menu:\n\nTo add a file to recent documents, you need to use the\napp.addRecentDocument API.\n\nExample\n\nAdd an item to recent documents\nStarting with a working application from the\nQuick Start Guide, add the following lines to the\nmain.js file:\nconst { app } = require('electron')\n\napp.addRecentDocument('/Users/USERNAME/Desktop/work.type')\n\nAfter launching the Electron application, right click the application icon.\nYou should see the item you just added. In this guide, the item is a Markdown\nfile located in the root of the project:\n\n\nClear the list of recent documents\nTo clear the list of recent documents, you need to use\napp.clearRecentDocuments API in the main.js file:\nconst { app } = require('electron')\n\napp.clearRecentDocuments()\n\n\nAdditional information\n\nWindows Notes\nTo use this feature on Windows, your application has to be registered as\na handler of the file type of the document, otherwise the file won't appear\nin JumpList even after you have added it. You can find everything\non registering your application in Application Registration.\nWhen a user clicks a file from the JumpList, a new instance of your application\nwill be started with the path of the file added as a command line argument.\n\nmacOS Notes\n\nAdd the Recent Documents list to the application menu\nYou can add menu items to access and clear recent documents by adding the\nfollowing code snippet to your menu template:\n{\n \"submenu\":[\n {\n \"label\":\"Open Recent\",\n \"role\":\"recentdocuments\",\n \"submenu\":[\n {\n \"label\":\"Clear Recent\",\n \"role\":\"clearrecentdocuments\"\n }\n ]\n }\n ]\n}\n\n\nWhen a file is requested from the recent documents menu, the open-file event\nof app module will be emitted for it.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Recent Documents (Windows & macOS)",
"doc:recent-documents",
"tutorial:Recent Documents (Windows & macOS)",
"tutorial:recent-documents"
]
},
{
"objectID": "tutorial-repl",
"title": "REPL",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/repl.md",
"url": "https://electronjs.org/docs/tutorial/repl",
"slug": "repl",
"body": "REPL\nRead-Eval-Print-Loop (REPL) is a simple, interactive computer programming\nenvironment that takes single user inputs (i.e. single expressions), evaluates\nthem, and returns the result to the user.\nThe repl module provides a REPL implementation that can be accessed using:\n\n\nAssuming you have electron or electron-prebuilt installed as a local\nproject dependency:\n./node_modules/.bin/electron --interactive\n\n\n\nAssuming you have electron or electron-prebuilt installed globally:\nelectron --interactive\n\n\n\nThis only creates a REPL for the main process. You can use the Console\ntab of the Dev Tools to get a REPL for the renderer processes.\nNote: electron --interactive is not available on Windows.\nMore information can be found in the Node.js REPL docs.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:REPL",
"doc:repl",
"tutorial:REPL",
"tutorial:repl"
]
},
{
"objectID": "tutorial-represented-file",
"title": "Represented File for macOS BrowserWindows",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/represented-file.md",
"url": "https://electronjs.org/docs/tutorial/represented-file",
"slug": "represented-file",
"body": "Represented File for macOS BrowserWindows\n\nOverview\nOn macOS, you can set a represented file for any window in your application.\nThe represented file's icon will be shown in the title bar, and when users\nCommand-Click or Control-Click, a popup with a path to the file will be\nshown.\n\n\nNOTE: The screenshot above is an example where this feature is used to indicate the currently opened file in the Atom text editor.\n\nYou can also set the edited state for a window so that the file icon can\nindicate whether the document in this window has been modified.\nTo set the represented file of window, you can use the\nBrowserWindow.setRepresentedFilename and\nBrowserWindow.setDocumentEdited APIs.\n\nExample\nStarting with a working application from the\nQuick Start Guide, add the following lines to the\nmain.js file:\nconst { app, BrowserWindow } = require('electron')\n\napp.whenReady().then(() => {\n const win = new BrowserWindow()\n\n win.setRepresentedFilename('/etc/passwd')\n win.setDocumentEdited(true)\n})\n\nAfter launching the Electron application, click on the title with Command or\nControl key pressed. You should see a popup with the file you just defined:\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Represented File for macOS BrowserWindows",
"doc:represented-file",
"tutorial:Represented File for macOS BrowserWindows",
"tutorial:represented-file"
]
},
{
"objectID": "tutorial-security",
"title": "Security, Native Capabilities, and Your Responsibility",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/security.md",
"url": "https://electronjs.org/docs/tutorial/security",
"slug": "security",
"body": "Security, Native Capabilities, and Your Responsibility\nAs web developers, we usually enjoy the strong security net of the browser -\nthe risks associated with the code we write are relatively small. Our websites\nare granted limited powers in a sandbox, and we trust that our users enjoy a\nbrowser built by a large team of engineers that is able to quickly respond to\nnewly discovered security threats.\nWhen working with Electron, it is important to understand that Electron is not\na web browser. It allows you to build feature-rich desktop applications with\nfamiliar web technologies, but your code wields much greater power. JavaScript\ncan access the filesystem, user shell, and more. This allows you to build\nhigh quality native applications, but the inherent security risks scale with\nthe additional powers granted to your code.\nWith that in mind, be aware that displaying arbitrary content from untrusted\nsources poses a severe security risk that Electron is not intended to handle.\nIn fact, the most popular Electron apps (Atom, Slack, Visual Studio Code, etc)\ndisplay primarily local content (or trusted, secure remote content without Node\nintegration) – if your application executes code from an online source, it is\nyour responsibility to ensure that the code is not malicious.\n\nReporting Security Issues\nFor information on how to properly disclose an Electron vulnerability,\nsee SECURITY.md\n\nChromium Security Issues and Upgrades\nElectron keeps up to date with alternating Chromium releases. For more information,\nsee the Electron Release Cadence blog post.\n\nSecurity Is Everyone's Responsibility\nIt is important to remember that the security of your Electron application is\nthe result of the overall security of the framework foundation\n(Chromium, Node.js), Electron itself, all NPM dependencies and\nyour code. As such, it is your responsibility to follow a few important best\npractices:\n\n\nKeep your application up-to-date with the latest Electron framework release.\nWhen releasing your product, youre also shipping a bundle composed of Electron,\nChromium shared library and Node.js. Vulnerabilities affecting these components\nmay impact the security of your application. By updating Electron to the latest\nversion, you ensure that critical vulnerabilities (such as nodeIntegration bypasses)\nare already patched and cannot be exploited in your application. For more information,\nsee \"Use a current version of Electron\".\n\n\nEvaluate your dependencies. While NPM provides half a million reusable packages,\nit is your responsibility to choose trusted 3rd-party libraries. If you use outdated\nlibraries affected by known vulnerabilities or rely on poorly maintained code,\nyour application security could be in jeopardy.\n\n\nAdopt secure coding practices. The first line of defense for your application\nis your own code. Common web vulnerabilities, such as Cross-Site Scripting (XSS),\nhave a higher security impact on Electron applications hence it is highly recommended\nto adopt secure software development best practices and perform security testing.\n\n\n\nIsolation For Untrusted Content\nA security issue exists whenever you receive code from an untrusted source (e.g.\na remote server) and execute it locally. As an example, consider a remote\nwebsite being displayed inside a default BrowserWindow. If\nan attacker somehow manages to change said content (either by attacking the\nsource directly, or by sitting between your app and the actual destination), they\nwill be able to execute native code on the user's machine.\n\n⚠ Under no circumstances should you load and execute remote code with\nNode.js integration enabled. Instead, use only local files (packaged together\nwith your application) to execute Node.js code. To display remote content, use\nthe <webview> tag or BrowserView, make sure\nto disable the nodeIntegration and enable contextIsolation.\n\n\nElectron Security Warnings\nFrom Electron 2.0 on, developers will see warnings and recommendations printed\nto the developer console. They only show up when the binary's name is Electron,\nindicating that a developer is currently looking at the console.\nYou can force-enable or force-disable these warnings by setting\nELECTRON_ENABLE_SECURITY_WARNINGS or ELECTRON_DISABLE_SECURITY_WARNINGS on\neither process.env or the window object.\n\nChecklist: Security Recommendations\nYou should at least follow these steps to improve the security of your application:\n\nOnly load secure content\nDisable the Node.js integration in all renderers that display remote content\nEnable context isolation in all renderers that display remote content\nUse ses.setPermissionRequestHandler() in all sessions that load remote content\nDo not disable webSecurity\nDefine a Content-Security-Policy and use restrictive rules (i.e. script-src 'self')\nDo not set allowRunningInsecureContent to true\nDo not enable experimental features\nDo not use enableBlinkFeatures\n<webview>: Do not use allowpopups\n<webview>: Verify options and params\nDisable or limit navigation\nDisable or limit creation of new windows\nDo not use openExternal with untrusted content\nUse a current version of Electron\n\nTo automate the detection of misconfigurations and insecure patterns, it is\npossible to use\nelectronegativity. For\nadditional details on potential weaknesses and implementation bugs when\ndeveloping applications using Electron, please refer to this guide for\ndevelopers and auditors\n\n1) Only Load Secure Content\nAny resources not included with your application should be loaded using a\nsecure protocol like HTTPS. In other words, do not use insecure protocols\nlike HTTP. Similarly, we recommend the use of WSS over WS, FTPS over\nFTP, and so on.\n\nWhy?\nHTTPS has three main benefits:\n1) It authenticates the remote server, ensuring your app connects to the correct\nhost instead of an impersonator.\n2) It ensures data integrity, asserting that the data was not modified while in\ntransit between your application and the host.\n3) It encrypts the traffic between your user and the destination host, making it\nmore difficult to eavesdrop on the information sent between your app and\nthe host.\n\nHow?\n// Bad\nbrowserWindow.loadURL('http://example.com')\n\n// Good\nbrowserWindow.loadURL('https://example.com')\n\n<!-- Bad -->\n<script crossorigin src=\"http://example.com/react.js\"></script>\n<link rel=\"stylesheet\" href=\"http://example.com/style.css\">\n\n<!-- Good -->\n<script crossorigin src=\"https://example.com/react.js\"></script>\n<link rel=\"stylesheet\" href=\"https://example.com/style.css\">\n\n\n2) Do not enable Node.js Integration for Remote Content\nThis recommendation is the default behavior in Electron since 5.0.0.\nIt is paramount that you do not enable Node.js integration in any renderer\n(BrowserWindow, BrowserView, or\n<webview>) that loads remote content. The goal is to limit the\npowers you grant to remote content, thus making it dramatically more difficult\nfor an attacker to harm your users should they gain the ability to execute\nJavaScript on your website.\nAfter this, you can grant additional permissions for specific hosts. For example,\nif you are opening a BrowserWindow pointed at https://example.com/, you can\ngive that website exactly the abilities it needs, but no more.\n\nWhy?\nA cross-site-scripting (XSS) attack is more dangerous if an attacker can jump\nout of the renderer process and execute code on the user's computer.\nCross-site-scripting attacks are fairly common - and while an issue, their\npower is usually limited to messing with the website that they are executed on.\nDisabling Node.js integration helps prevent an XSS from being escalated into a\nso-called \"Remote Code Execution\" (RCE) attack.\n\nHow?\n// Bad\nconst mainWindow = new BrowserWindow({\n webPreferences: {\n nodeIntegration: true,\n nodeIntegrationInWorker: true\n }\n})\n\nmainWindow.loadURL('https://example.com')\n\n// Good\nconst mainWindow = new BrowserWindow({\n webPreferences: {\n preload: path.join(app.getAppPath(), 'preload.js')\n }\n})\n\nmainWindow.loadURL('https://example.com')\n\n<!-- Bad -->\n<webview nodeIntegration src=\"page.html\"></webview>\n\n<!-- Good -->\n<webview src=\"page.html\"></webview>\n\nWhen disabling Node.js integration, you can still expose APIs to your website that\ndo consume Node.js modules or features. Preload scripts continue to have access\nto require and other Node.js features, allowing developers to expose a custom\nAPI to remotely loaded content.\nIn the following example preload script, the later loaded website will have\naccess to a window.readConfig() method, but no Node.js features.\nconst { readFileSync } = require('fs')\n\nwindow.readConfig = function () {\n const data = readFileSync('./config.json')\n return data\n}\n\n\n3) Enable Context Isolation for Remote Content\nContext isolation is an Electron feature that allows developers to run code\nin preload scripts and in Electron APIs in a dedicated JavaScript context. In\npractice, that means that global objects like Array.prototype.push or\nJSON.parse cannot be modified by scripts running in the renderer process.\nElectron uses the same technology as Chromium's Content Scripts\nto enable this behavior.\nEven when nodeIntegration: false is used, to truly enforce strong isolation\nand prevent the use of Node primitives contextIsolation must also be used.\n\nWhy & How?\nFor more information on what contextIsolation is and how to enable it please\nsee our dedicated Context Isolation document.\n\n4) Handle Session Permission Requests From Remote Content\nYou may have seen permission requests while using Chrome: They pop up whenever\nthe website attempts to use a feature that the user has to manually approve (\nlike notifications).\nThe API is based on the Chromium permissions API\nand implements the same types of permissions.\n\nWhy?\nBy default, Electron will automatically approve all permission requests unless\nthe developer has manually configured a custom handler. While a solid default,\nsecurity-conscious developers might want to assume the very opposite.\n\nHow?\nconst { session } = require('electron')\n\nsession\n .fromPartition('some-partition')\n .setPermissionRequestHandler((webContents, permission, callback) => {\n const url = webContents.getURL()\n\n if (permission === 'notifications') {\n // Approves the permissions request\n callback(true)\n }\n\n // Verify URL\n if (!url.startsWith('https://example.com/')) {\n // Denies the permissions request\n return callback(false)\n }\n })\n\n\n5) Do Not Disable WebSecurity\nRecommendation is Electron's default\nYou may have already guessed that disabling the webSecurity property on a\nrenderer process (BrowserWindow,\nBrowserView, or <webview>) disables crucial\nsecurity features.\nDo not disable webSecurity in production applications.\n\nWhy?\nDisabling webSecurity will disable the same-origin policy and set\nallowRunningInsecureContent property to true. In other words, it allows\nthe execution of insecure code from different domains.\n\nHow?\n// Bad\nconst mainWindow = new BrowserWindow({\n webPreferences: {\n webSecurity: false\n }\n})\n\n// Good\nconst mainWindow = new BrowserWindow()\n\n<!-- Bad -->\n<webview disablewebsecurity src=\"page.html\"></webview>\n\n<!-- Good -->\n<webview src=\"page.html\"></webview>\n\n\n6) Define a Content Security Policy\nA Content Security Policy (CSP) is an additional layer of protection against\ncross-site-scripting attacks and data injection attacks. We recommend that they\nbe enabled by any website you load inside Electron.\n\nWhy?\nCSP allows the server serving content to restrict and control the resources\nElectron can load for that given web page. https://example.com should\nbe allowed to load scripts from the origins you defined while scripts from\nhttps://evil.attacker.com should not be allowed to run. Defining a CSP is an\neasy way to improve your application's security.\nThe following CSP will allow Electron to execute scripts from the current\nwebsite and from apis.example.com.\n// Bad\nContent-Security-Policy: '*'\n\n// Good\nContent-Security-Policy: script-src 'self' https://apis.example.com\n\n\nCSP HTTP Header\nElectron respects the Content-Security-Policy HTTP header\nwhich can be set using Electron's\nwebRequest.onHeadersReceived\nhandler:\nconst { session } = require('electron')\n\nsession.defaultSession.webRequest.onHeadersReceived((details, callback) => {\n callback({\n responseHeaders: {\n ...details.responseHeaders,\n 'Content-Security-Policy': ['default-src \\'none\\'']\n }\n })\n})\n\n\nCSP Meta Tag\nCSP's preferred delivery mechanism is an HTTP header, however it is not possible\nto use this method when loading a resource using the file:// protocol. It can\nbe useful in some cases, such as using the file:// protocol, to set a policy\non a page directly in the markup using a <meta> tag:\n<meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'none'\">\n\n\n7) Do Not Set allowRunningInsecureContent to true\nRecommendation is Electron's default\nBy default, Electron will not allow websites loaded over HTTPS to load and\nexecute scripts, CSS, or plugins from insecure sources (HTTP). Setting the\nproperty allowRunningInsecureContent to true disables that protection.\nLoading the initial HTML of a website over HTTPS and attempting to load\nsubsequent resources via HTTP is also known as \"mixed content\".\n\nWhy?\nLoading content over HTTPS assures the authenticity and integrity\nof the loaded resources while encrypting the traffic itself. See the section on\nonly displaying secure content for more details.\n\nHow?\n// Bad\nconst mainWindow = new BrowserWindow({\n webPreferences: {\n allowRunningInsecureContent: true\n }\n})\n\n// Good\nconst mainWindow = new BrowserWindow({})\n\n\n8) Do Not Enable Experimental Features\nRecommendation is Electron's default\nAdvanced users of Electron can enable experimental Chromium features using the\nexperimentalFeatures property.\n\nWhy?\nExperimental features are, as the name suggests, experimental and have not been\nenabled for all Chromium users. Furthermore, their impact on Electron as a whole\nhas likely not been tested.\nLegitimate use cases exist, but unless you know what you are doing, you should\nnot enable this property.\n\nHow?\n// Bad\nconst mainWindow = new BrowserWindow({\n webPreferences: {\n experimentalFeatures: true\n }\n})\n\n// Good\nconst mainWindow = new BrowserWindow({})\n\n\n9) Do Not Use enableBlinkFeatures\nRecommendation is Electron's default\nBlink is the name of the rendering engine behind Chromium. As with\nexperimentalFeatures, the enableBlinkFeatures property allows developers to\nenable features that have been disabled by default.\n\nWhy?\nGenerally speaking, there are likely good reasons if a feature was not enabled\nby default. Legitimate use cases for enabling specific features exist. As a\ndeveloper, you should know exactly why you need to enable a feature, what the\nramifications are, and how it impacts the security of your application. Under\nno circumstances should you enable features speculatively.\n\nHow?\n// Bad\nconst mainWindow = new BrowserWindow({\n webPreferences: {\n enableBlinkFeatures: 'ExecCommandInJavaScript'\n }\n})\n\n// Good\nconst mainWindow = new BrowserWindow()\n\n\n10) Do Not Use allowpopups\nRecommendation is Electron's default\nIf you are using <webview>, you might need the pages and scripts\nloaded in your <webview> tag to open new windows. The allowpopups attribute\nenables them to create new BrowserWindows using the\nwindow.open() method. <webview> tags are otherwise not allowed to create new\nwindows.\n\nWhy?\nIf you do not need popups, you are better off not allowing the creation of\nnew BrowserWindows by default. This follows the principle\nof minimally required access: Don't let a website create new popups unless\nyou know it needs that feature.\n\nHow?\n<!-- Bad -->\n<webview allowpopups src=\"page.html\"></webview>\n\n<!-- Good -->\n<webview src=\"page.html\"></webview>\n\n\n11) Verify WebView Options Before Creation\nA WebView created in a renderer process that does not have Node.js integration\nenabled will not be able to enable integration itself. However, a WebView will\nalways create an independent renderer process with its own webPreferences.\nIt is a good idea to control the creation of new <webview> tags\nfrom the main process and to verify that their webPreferences do not disable\nsecurity features.\n\nWhy?\nSince <webview> live in the DOM, they can be created by a script running on your\nwebsite even if Node.js integration is otherwise disabled.\nElectron enables developers to disable various security features that control\na renderer process. In most cases, developers do not need to disable any of\nthose features - and you should therefore not allow different configurations\nfor newly created <webview> tags.\n\nHow?\nBefore a <webview> tag is attached, Electron will fire the\nwill-attach-webview event on the hosting webContents. Use the event to\nprevent the creation of webViews with possibly insecure options.\napp.on('web-contents-created', (event, contents) => {\n contents.on('will-attach-webview', (event, webPreferences, params) => {\n // Strip away preload scripts if unused or verify their location is legitimate\n delete webPreferences.preload\n delete webPreferences.preloadURL\n\n // Disable Node.js integration\n webPreferences.nodeIntegration = false\n\n // Verify URL being loaded\n if (!params.src.startsWith('https://example.com/')) {\n event.preventDefault()\n }\n })\n})\n\nAgain, this list merely minimizes the risk, it does not remove it. If your goal\nis to display a website, a browser will be a more secure option.\n\n12) Disable or limit navigation\nIf your app has no need to navigate or only needs to navigate to known pages,\nit is a good idea to limit navigation outright to that known scope, disallowing\nany other kinds of navigation.\n\nWhy?\nNavigation is a common attack vector. If an attacker can convince your app to\nnavigate away from its current page, they can possibly force your app to open\nweb sites on the Internet. Even if your webContents are configured to be more\nsecure (like having nodeIntegration disabled or contextIsolation enabled),\ngetting your app to open a random web site will make the work of exploiting your\napp a lot easier.\nA common attack pattern is that the attacker convinces your app's users to\ninteract with the app in such a way that it navigates to one of the attacker's\npages. This is usually done via links, plugins, or other user-generated content.\n\nHow?\nIf your app has no need for navigation, you can call event.preventDefault()\nin a will-navigate handler. If you know which pages your app\nmight navigate to, check the URL in the event handler and only let navigation\noccur if it matches the URLs you're expecting.\nWe recommend that you use Node's parser for URLs. Simple string comparisons can\nsometimes be fooled - a startsWith('https://example.com') test would let\nhttps://example.com.attacker.com through.\nconst URL = require('url').URL\n\napp.on('web-contents-created', (event, contents) => {\n contents.on('will-navigate', (event, navigationUrl) => {\n const parsedUrl = new URL(navigationUrl)\n\n if (parsedUrl.origin !== 'https://example.com') {\n event.preventDefault()\n }\n })\n})\n\n\n13) Disable or limit creation of new windows\nIf you have a known set of windows, it's a good idea to limit the creation of\nadditional windows in your app.\n\nWhy?\nMuch like navigation, the creation of new webContents is a common attack\nvector. Attackers attempt to convince your app to create new windows, frames,\nor other renderer processes with more privileges than they had before; or\nwith pages opened that they couldn't open before.\nIf you have no need to create windows in addition to the ones you know you'll\nneed to create, disabling the creation buys you a little bit of extra\nsecurity at no cost. This is commonly the case for apps that open one\nBrowserWindow and do not need to open an arbitrary number of additional\nwindows at runtime.\n\nHow?\nwebContents will delegate to its window open\nhandler before creating new windows. The handler will\nreceive, amongst other parameters, the url the window was requested to open\nand the options used to create it. We recommend that you register a handler to\nmonitor the creation of windows, and deny any unexpected window creation.\nconst { shell } = require('electron')\n\napp.on('web-contents-created', (event, contents) => {\n contents.setWindowOpenHandler(({ url }) => {\n // In this example, we'll ask the operating system\n // to open this event's url in the default browser.\n //\n // See the following item for considerations regarding what\n // URLs should be allowed through to shell.openExternal.\n if (isSafeForExternalOpen(url)) {\n setImmediate(() => {\n shell.openExternal(url)\n })\n }\n\n return { action: 'deny' }\n })\n})\n\n\n14) Do not use openExternal with untrusted content\nShell's openExternal allows opening a given protocol URI with\nthe desktop's native utilities. On macOS, for instance, this function is similar\nto the open terminal command utility and will open the specific application\nbased on the URI and filetype association.\n\nWhy?\nImproper use of openExternal can be leveraged to compromise\nthe user's host. When openExternal is used with untrusted content, it can be\nleveraged to execute arbitrary commands.\n\nHow?\n// Bad\nconst { shell } = require('electron')\nshell.openExternal(USER_CONTROLLED_DATA_HERE)\n\n// Good\nconst { shell } = require('electron')\nshell.openExternal('https://example.com/index.html')\n\n\n15) Use a current version of Electron\nYou should strive for always using the latest available version of Electron.\nWhenever a new major version is released, you should attempt to update your\napp as quickly as possible.\n\nWhy?\nAn application built with an older version of Electron, Chromium, and Node.js\nis an easier target than an application that is using more recent versions of\nthose components. Generally speaking, security issues and exploits for older\nversions of Chromium and Node.js are more widely available.\nBoth Chromium and Node.js are impressive feats of engineering built by\nthousands of talented developers. Given their popularity, their security is\ncarefully tested and analyzed by equally skilled security researchers. Many of\nthose researchers disclose vulnerabilities responsibly,\nwhich generally means that researchers will give Chromium and Node.js some time\nto fix issues before publishing them. Your application will be more secure if\nit is running a recent version of Electron (and thus, Chromium and Node.js) for\nwhich potential security issues are not as widely known.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Security, Native Capabilities, and Your Responsibility",
"doc:security",
"tutorial:Security, Native Capabilities, and Your Responsibility",
"tutorial:security"
]
},
{
"objectID": "tutorial-setting-up-symbol-server",
"title": "Setting Up Symbol Server in Debugger",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/development/setting-up-symbol-server.md",
"url": "https://electronjs.org/docs/development/setting-up-symbol-server",
"slug": "setting-up-symbol-server",
"body": "Setting Up Symbol Server in Debugger\nDebug symbols allow you to have better debugging sessions. They have information\nabout the functions contained in executables and dynamic libraries and provide\nyou with information to get clean call stacks. A Symbol Server allows the\ndebugger to load the correct symbols, binaries and sources automatically without\nforcing users to download large debugging files. The server functions like\nMicrosoft's symbol server so the\ndocumentation there can be useful.\nNote that because released Electron builds are heavily optimized, debugging is\nnot always easy. The debugger will not be able to show you the content of all\nvariables and the execution path can seem strange because of inlining, tail\ncalls, and other compiler optimizations. The only workaround is to build an\nunoptimized local build.\nThe official symbol server URL for Electron is\nhttps://symbols.electronjs.org.\nYou cannot visit this URL directly, you must add it to the symbol path of your\ndebugging tool. In the examples below, a local cache directory is used to avoid\nrepeatedly fetching the PDB from the server. Replace c:\\code\\symbols with an\nappropriate cache directory on your machine.\n\nUsing the Symbol Server in Windbg\nThe Windbg symbol path is configured with a string value delimited with asterisk\ncharacters. To use only the Electron symbol server, add the following entry to\nyour symbol path (Note: you can replace c:\\code\\symbols with any writable\ndirectory on your computer, if you'd prefer a different location for downloaded\nsymbols):\nSRV*c:\\code\\symbols\\*https://symbols.electronjs.org\n\nSet this string as _NT_SYMBOL_PATH in the environment, using the Windbg menus,\nor by typing the .sympath command. If you would like to get symbols from\nMicrosoft's symbol server as well, you should list that first:\nSRV*c:\\code\\symbols\\*https://msdl.microsoft.com/download/symbols;SRV*c:\\code\\symbols\\*https://symbols.electronjs.org\n\n\nUsing the symbol server in Visual Studio\n\n\n\nTroubleshooting: Symbols will not load\nType the following commands in Windbg to print why symbols are not loading:\n> !sym noisy\n> .reload /f electron.exe\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Setting Up Symbol Server in Debugger",
"doc:setting-up-symbol-server",
"tutorial:Setting Up Symbol Server in Debugger",
"tutorial:setting-up-symbol-server"
]
},
{
"objectID": "tutorial-snapcraft",
"title": "Snapcraft Guide (Ubuntu Software Center & More)",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/snapcraft.md",
"url": "https://electronjs.org/docs/tutorial/snapcraft",
"slug": "snapcraft",
"body": "Snapcraft Guide (Ubuntu Software Center & More)\nThis guide provides information on how to package your Electron application\nfor any Snapcraft environment, including the Ubuntu Software Center.\n\nBackground and Requirements\nTogether with the broader Linux community, Canonical aims to fix many of the\ncommon software installation problems with the snapcraft\nproject. Snaps are containerized software packages that include required\ndependencies, auto-update, and work on all major Linux distributions without\nsystem modification.\nThere are three ways to create a .snap file:\n1) Using electron-forge or\nelectron-builder, both tools that come with snap\nsupport out of the box. This is the easiest option.\n2) Using electron-installer-snap, which takes electron-packager's output.\n3) Using an already created .deb package.\nIn some cases, you will need to have the snapcraft tool installed.\nInstructions to install snapcraft for your particular distribution are\navailable here.\n\nUsing electron-installer-snap\nThe module works like electron-winstaller and similar\nmodules in that its scope is limited to building snap packages. You can install\nit with:\nnpm install --save-dev electron-installer-snap\n\n\nStep 1: Package Your Electron Application\nPackage the application using electron-packager (or a\nsimilar tool). Make sure to remove node_modules that you don't need in your\nfinal application, since any module you don't actually need will increase\nyour application's size.\nThe output should look roughly like this:\n.\n└── dist\n └── app-linux-x64\n ├── LICENSE\n ├── LICENSES.chromium.html\n ├── content_shell.pak\n ├── app\n ├── icudtl.dat\n ├── libgcrypt.so.11\n ├── libnode.so\n ├── locales\n ├── resources\n ├── v8_context_snapshot.bin\n └── version\n\n\nStep 2: Running electron-installer-snap\nFrom a terminal that has snapcraft in its PATH, run electron-installer-snap\nwith the only required parameter --src, which is the location of your packaged\nElectron application created in the first step.\nnpx electron-installer-snap --src=out/myappname-linux-x64\n\nIf you have an existing build pipeline, you can use electron-installer-snap\nprogrammatically. For more information, see the Snapcraft API docs.\nconst snap = require('electron-installer-snap')\n\nsnap(options)\n .then(snapPath => console.log(`Created snap at ${snapPath}!`))\n\n\nUsing snapcraft with electron-packager\n\nStep 1: Create Sample Snapcraft Project\nCreate your project directory and add the following to snap/snapcraft.yaml:\nname: electron-packager-hello-world\nversion: '0.1'\nsummary: Hello World Electron app\ndescription: |\n Simple Hello World Electron app as an example\nbase: core18\nconfinement: strict\ngrade: stable\n\napps:\n electron-packager-hello-world:\n command: electron-quick-start/electron-quick-start --no-sandbox\n extensions: [gnome-3-34]\n plugs:\n - browser-support\n - network\n - network-bind\n environment:\n # Correct the TMPDIR path for Chromium Framework/Electron to ensure\n # libappindicator has readable resources.\n TMPDIR: $XDG_RUNTIME_DIR\n\nparts:\n electron-quick-start:\n plugin: nil\n source: https://github.com/electron/electron-quick-start.git\n override-build: |\n npm install electron electron-packager\n npx electron-packager . --overwrite --platform=linux --output=release-build --prune=true\n cp -rv ./electron-quick-start-linux-* $SNAPCRAFT_PART_INSTALL/electron-quick-start\n build-snaps:\n - node/14/stable\n build-packages:\n - unzip\n stage-packages:\n - libnss3\n - libnspr4\n\nIf you want to apply this example to an existing project:\n\nReplace source: https://github.com/electron/electron-quick-start.git with source: ..\nReplace all instances of electron-quick-start with your project's name.\n\n\nStep 2: Build the snap\n$ snapcraft\n\n<output snipped>\nSnapped electron-packager-hello-world_0.1_amd64.snap\n\n\nStep 3: Install the snap\nsudo snap install electron-packager-hello-world_0.1_amd64.snap --dangerous\n\n\nStep 4: Run the snap\nelectron-packager-hello-world\n\n\nUsing an Existing Debian Package\nSnapcraft is capable of taking an existing .deb file and turning it into\na .snap file. The creation of a snap is configured using a snapcraft.yaml\nfile that describes the sources, dependencies, description, and other core\nbuilding blocks.\n\nStep 1: Create a Debian Package\nIf you do not already have a .deb package, using electron-installer-snap\nmight be an easier path to create snap packages. However, multiple solutions\nfor creating Debian packages exist, including electron-forge,\nelectron-builder or\nelectron-installer-debian.\n\nStep 2: Create a snapcraft.yaml\nFor more information on the available configuration options, see the\ndocumentation on the snapcraft syntax.\nLet's look at an example:\nname: myApp\nversion: '2.0.0'\nsummary: A little description for the app.\ndescription: |\n You know what? This app is amazing! It does all the things\n for you. Some say it keeps you young, maybe even happy.\n\ngrade: stable\nconfinement: classic\n\nparts:\n slack:\n plugin: dump\n source: my-deb.deb\n source-type: deb\n after:\n - desktop-gtk3\n stage-packages:\n - libasound2\n - libnotify4\n - libnspr4\n - libnss3\n - libpcre3\n - libpulse0\n - libxss1\n - libxtst6\n electron-launch:\n plugin: dump\n source: files/\n prepare: |\n chmod +x bin/electron-launch\n\napps:\n myApp:\n command: bin/electron-launch $SNAP/usr/lib/myApp/myApp\n desktop: usr/share/applications/myApp.desktop\n # Correct the TMPDIR path for Chromium Framework/Electron to ensure\n # libappindicator has readable resources.\n environment:\n TMPDIR: $XDG_RUNTIME_DIR\n\nAs you can see, the snapcraft.yaml instructs the system to launch a file\ncalled electron-launch. In this example, it passes information on to the\napp's binary:\n#!/bin/sh\n\nexec \"$@\" --executed-from=\"$(pwd)\" --pid=$$ > /dev/null 2>&1 &\n\nAlternatively, if you're building your snap with strict confinement, you\ncan use the desktop-launch command:\napps:\n myApp:\n # Correct the TMPDIR path for Chromium Framework/Electron to ensure\n # libappindicator has readable resources.\n command: env TMPDIR=$XDG_RUNTIME_DIR PATH=/usr/local/bin:${PATH} ${SNAP}/bin/desktop-launch $SNAP/myApp/desktop\n desktop: usr/share/applications/desktop.desktop\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Snapcraft Guide (Ubuntu Software Center & More)",
"doc:snapcraft",
"tutorial:Snapcraft Guide (Ubuntu Software Center & More)",
"tutorial:snapcraft"
]
},
{
"objectID": "tutorial-source-code-directory-structure",
"title": "Source Code Directory Structure",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/development/source-code-directory-structure.md",
"url": "https://electronjs.org/docs/development/source-code-directory-structure",
"slug": "source-code-directory-structure",
"body": "Source Code Directory Structure\nThe source code of Electron is separated into a few parts, mostly\nfollowing Chromium on the separation conventions.\nYou may need to become familiar with Chromium's multi-process\narchitecture\nto understand the source code better.\n\nStructure of Source Code\nElectron\n├── build/ - Build configuration files needed to build with GN.\n├── buildflags/ - Determines the set of features that can be conditionally built.\n├── chromium_src/ - Source code copied from Chromium that isn't part of the content layer.\n├── default_app/ - A default app run when Electron is started without\n| providing a consumer app.\n├── docs/ - Electron's documentation.\n| ├── api/ - Documentation for Electron's externally-facing modules and APIs.\n| ├── development/ - Documentation to aid in developing for and with Electron.\n| ├── fiddles/ - A set of code snippets one can run in Electron Fiddle.\n| ├── images/ - Images used in documentation.\n| └── tutorial/ - Tutorial documents for various aspects of Electron.\n├── lib/ - JavaScript/TypeScript source code.\n| ├── browser/ - Main process initialization code.\n| | ├── api/ - API implementation for main process modules.\n| | └── remote/ - Code related to the remote module as it is\n| | used in the main process.\n| ├── common/ - Relating to logic needed by both main and renderer processes.\n| | └── api/ - API implementation for modules that can be used in\n| | both the main and renderer processes\n| ├── isolated_renderer/ - Handles creation of isolated renderer processes when\n| | contextIsolation is enabled.\n| ├── renderer/ - Renderer process initialization code.\n| | ├── api/ - API implementation for renderer process modules.\n| | ├── extension/ - Code related to use of Chrome Extensions\n| | | in Electron's renderer process.\n| | ├── remote/ - Logic that handles use of the remote module in\n| | | the main process.\n| | └── web-view/ - Logic that handles the use of webviews in the\n| | renderer process.\n| ├── sandboxed_renderer/ - Logic that handles creation of sandboxed renderer\n| | | processes.\n| | └── api/ - API implementation for sandboxed renderer processes.\n| └── worker/ - Logic that handles proper functionality of Node.js\n| environments in Web Workers.\n├── patches/ - Patches applied on top of Electron's core dependencies\n| | in order to handle differences between our use cases and\n| | default functionality.\n| ├── boringssl/ - Patches applied to Google's fork of OpenSSL, BoringSSL.\n| ├── chromium/ - Patches applied to Chromium.\n| ├── node/ - Patches applied on top of Node.js.\n| └── v8/ - Patches applied on top of Google's V8 engine.\n├── shell/ - C++ source code.\n| ├── app/ - System entry code.\n| ├── browser/ - The frontend including the main window, UI, and all of the\n| | | main process things. This talks to the renderer to manage web\n| | | pages.\n| | ├── ui/ - Implementation of UI stuff for different platforms.\n| | | ├── cocoa/ - Cocoa specific source code.\n| | | ├── win/ - Windows GUI specific source code.\n| | | └── x/ - X11 specific source code.\n| | ├── api/ - The implementation of the main process APIs.\n| | ├── net/ - Network related code.\n| | ├── mac/ - Mac specific Objective-C source code.\n| | └── resources/ - Icons, platform-dependent files, etc.\n| ├── renderer/ - Code that runs in renderer process.\n| | └── api/ - The implementation of renderer process APIs.\n| └── common/ - Code that used by both the main and renderer processes,\n| | including some utility functions and code to integrate node's\n| | message loop into Chromium's message loop.\n| └── api/ - The implementation of common APIs, and foundations of\n| Electron's built-in modules.\n├── spec/ - Components of Electron's test suite run in the renderer process.\n├── spec-main/ - Components of Electron's test suite run in the main process.\n└── BUILD.gn - Building rules of Electron.\n\n\nStructure of Other Directories\n\n.circleci - Config file for CI with CircleCI.\n.github - GitHub-specific config files including issues templates and CODEOWNERS.\ndist - Temporary directory created by script/create-dist.py script\nwhen creating a distribution.\nexternal_binaries - Downloaded binaries of third-party frameworks which\ndo not support building with gn.\nnode_modules - Third party node modules used for building.\nnpm - Logic for installation of Electron via npm.\nout - Temporary output directory of ninja.\nscript - Scripts used for development purpose like building, packaging,\ntesting, etc.\n\nscript/ - The set of all scripts Electron runs for a variety of purposes.\n├── codesign/ - Fakes codesigning for Electron apps; used for testing.\n├── lib/ - Miscellaneous python utility scripts.\n└── release/ - Scripts run during Electron's release process.\n ├── notes/ - Generates release notes for new Electron versions.\n └── uploaders/ - Uploads various release-related files during release.\n\n\ntools - Helper scripts used by GN files.\nScripts put here should never be invoked by users directly, unlike those in script.\n\ntypings - TypeScript typings for Electron's internal code.\nvendor - Source code for some third party dependencies.\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Source Code Directory Structure",
"doc:source-code-directory-structure",
"tutorial:Source Code Directory Structure",
"tutorial:source-code-directory-structure"
]
},
{
"objectID": "tutorial-spellchecker",
"title": "SpellChecker",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/spellchecker.md",
"url": "https://electronjs.org/docs/tutorial/spellchecker",
"slug": "spellchecker",
"body": "SpellChecker\nElectron has built-in support for Chromium's spellchecker since Electron 8. On Windows and Linux this is powered by Hunspell dictionaries, and on macOS it makes use of the native spellchecker APIs.\n\nHow to enable the spellchecker?\nFor Electron 9 and higher the spellchecker is enabled by default. For Electron 8 you need to enable it in webPreferences.\nconst myWindow = new BrowserWindow({\n webPreferences: {\n spellcheck: true\n }\n})\n\n\nHow to set the languages the spellchecker uses?\nOn macOS as we use the native APIs there is no way to set the language that the spellchecker uses. By default on macOS the native spellchecker will automatically detect the language being used for you.\nFor Windows and Linux there are a few Electron APIs you should use to set the languages for the spellchecker.\n// Sets the spellchecker to check English US and French\nmyWindow.session.setSpellCheckerLanguages(['en-US', 'fr'])\n\n// An array of all available language codes\nconst possibleLanguages = myWindow.session.availableSpellCheckerLanguages\n\nBy default the spellchecker will enable the language matching the current OS locale.\n\nHow do I put the results of the spellchecker in my context menu?\nAll the required information to generate a context menu is provided in the context-menu event on each webContents instance. A small example\nof how to make a context menu with this information is provided below.\nconst { Menu, MenuItem } = require('electron')\n\nmyWindow.webContents.on('context-menu', (event, params) => {\n const menu = new Menu()\n\n // Add each spelling suggestion\n for (const suggestion of params.dictionarySuggestions) {\n menu.append(new MenuItem({\n label: suggestion,\n click: () => mainWindow.webContents.replaceMisspelling(suggestion)\n }))\n }\n\n // Allow users to add the misspelled word to the dictionary\n if (params.misspelledWord) {\n menu.append(\n new MenuItem({\n label: 'Add to dictionary',\n click: () => mainWindow.webContents.session.addWordToSpellCheckerDictionary(params.misspelledWord)\n })\n )\n }\n\n menu.popup()\n})\n\n\nDoes the spellchecker use any Google services?\nAlthough the spellchecker itself does not send any typings, words or user input to Google services the hunspell dictionary files are downloaded from a Google CDN by default. If you want to avoid this you can provide an alternative URL to download the dictionaries from.\nmyWindow.session.setSpellCheckerDictionaryDownloadURL('https://example.com/dictionaries/')\n\nCheck out the docs for session.setSpellCheckerDictionaryDownloadURL for more information on where to get the dictionary files from and how you need to host them.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:SpellChecker",
"doc:spellchecker",
"tutorial:SpellChecker",
"tutorial:spellchecker"
]
},
{
"objectID": "tutorial-styleguide",
"title": "Electron Documentation Style Guide",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/styleguide.md",
"url": "https://electronjs.org/docs/styleguide",
"slug": "styleguide",
"body": "Electron Documentation Style Guide\nThese are the guidelines for writing Electron documentation.\n\nTitles\n\nEach page must have a single #-level title at the top.\nChapters in the same page must have ##-level titles.\nSub-chapters need to increase the number of # in the title according to\ntheir nesting depth.\nAll words in the page's title must be capitalized, except for conjunctions\nlike \"of\" and \"and\" .\nOnly the first word of a chapter title must be capitalized.\n\nUsing Quick Start as example:\n# Quick Start\n\n...\n\n## Main process\n\n...\n\n## Renderer process\n\n...\n\n## Run your app\n\n...\n\n### Run as a distribution\n\n...\n\n### Manually downloaded Electron binary\n\n...\n\nFor API references, there are exceptions to this rule.\n\nMarkdown rules\n\nUse sh instead of cmd in code blocks (due to the syntax highlighter).\nLines should be wrapped at 80 columns.\nNo nesting lists more than 2 levels (due to the markdown renderer).\nAll js and javascript code blocks are linted with\nstandard-markdown.\nFor unordered lists, use asterisks instead of dashes\n\n\nPicking words\n\nUse \"will\" over \"would\" when describing outcomes.\nPrefer \"in the ___ process\" over \"on\".\n\n\nAPI references\nThe following rules only apply to the documentation of APIs.\n\nPage title\nEach page must use the actual object name returned by require('electron')\nas the title, such as BrowserWindow, autoUpdater, and session.\nUnder the page title must be a one-line description starting with >.\nUsing session as example:\n# session\n\n> Manage browser sessions, cookies, cache, proxy settings, etc.\n\n\nModule methods and events\nFor modules that are not classes, their methods and events must be listed under\nthe ## Methods and ## Events chapters.\nUsing autoUpdater as an example:\n# autoUpdater\n\n## Events\n\n### Event: 'error'\n\n## Methods\n\n### `autoUpdater.setFeedURL(url[, requestHeaders])`\n\n\nClasses\n\nAPI classes or classes that are part of modules must be listed under a\n## Class: TheClassName chapter.\nOne page can have multiple classes.\nConstructors must be listed with ###-level titles.\nStatic Methods must be listed under a ### Static Methods chapter.\nInstance Methods must be listed under an ### Instance Methods chapter.\nAll methods that have a return value must start their description with \"Returns [TYPE] - Return description\"\nIf the method returns an Object, its structure can be specified using a colon followed by a newline then an unordered list of properties in the same style as function parameters.\n\nInstance Events must be listed under an ### Instance Events chapter.\nInstance Properties must be listed under an ### Instance Properties chapter.\nInstance properties must start with \"A [Property Type] ...\"\n\n\nUsing the Session and Cookies classes as an example:\n# session\n\n## Methods\n\n### session.fromPartition(partition)\n\n## Static Properties\n\n### session.defaultSession\n\n## Class: Session\n\n### Instance Events\n\n#### Event: 'will-download'\n\n### Instance Methods\n\n#### `ses.getCacheSize()`\n\n### Instance Properties\n\n#### `ses.cookies`\n\n## Class: Cookies\n\n### Instance Methods\n\n#### `cookies.get(filter, callback)`\n\n\nMethods\nThe methods chapter must be in the following form:\n### `objectName.methodName(required[, optional]))`\n\n* `required` String - A parameter description.\n* `optional` Integer (optional) - Another parameter description.\n\n...\n\nThe title can be ### or ####-levels depending on whether it is a method of\na module or a class.\nFor modules, the objectName is the module's name. For classes, it must be the\nname of the instance of the class, and must not be the same as the module's\nname.\nFor example, the methods of the Session class under the session module must\nuse ses as the objectName.\nThe optional arguments are notated by square brackets [] surrounding the optional argument\nas well as the comma required if this optional argument follows another\nargument:\nrequired[, optional]\n\nBelow the method is more detailed information on each of the arguments. The type\nof argument is notated by either the common types:\n\nString\nNumber\nObject\nArray\nBoolean\nOr a custom type like Electron's WebContent\n\nIf an argument or a method is unique to certain platforms, those platforms are\ndenoted using a space-delimited italicized list following the datatype. Values\ncan be macOS, Windows or Linux.\n* `animate` Boolean (optional) _macOS_ _Windows_ - Animate the thing.\n\nArray type arguments must specify what elements the array may include in\nthe description below.\nThe description for Function type arguments should make it clear how it may be\ncalled and list the types of the parameters that will be passed to it.\n\nEvents\nThe events chapter must be in following form:\n### Event: 'wake-up'\n\nReturns:\n\n* `time` String\n\n...\n\nThe title can be ### or ####-levels depending on whether it is an event of\na module or a class.\nThe arguments of an event follow the same rules as methods.\n\nProperties\nThe properties chapter must be in following form:\n### session.defaultSession\n\n...\n\nThe title can be ### or ####-levels depending on whether it is a property of\na module or a class.\n\nDocumentation Translations\nSee electron/i18n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Electron Documentation Style Guide",
"doc:styleguide",
"tutorial:Electron Documentation Style Guide",
"tutorial:styleguide"
]
},
{
"objectID": "tutorial-support",
"title": "Electron Support",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/support.md",
"url": "https://electronjs.org/docs/tutorial/support",
"slug": "support",
"body": "Electron Support\n\nFinding Support\nIf you have a security concern,\nplease see the security document.\nIf you're looking for programming help,\nfor answers to questions,\nor to join in discussion with other developers who use Electron,\nyou can interact with the community in these locations:\n\nElectron's Discord has channels for:\nGetting help\nEcosystem apps like Electron Forge and Electron Fiddle\nSharing ideas with other Electron app developers\nAnd more!\n\nelectron category on the Atom forums\n#atom-shell channel on Freenode\n#electron channel on Atom's Slack\nelectron-ru (Russian)\nelectron-br (Brazilian Portuguese)\nelectron-kr (Korean)\nelectron-jp (Japanese)\nelectron-tr (Turkish)\nelectron-id (Indonesia)\nelectron-pl (Poland)\n\nIf you'd like to contribute to Electron,\nsee the contributing document.\nIf you've found a bug in a supported version of Electron,\nplease report it with the issue tracker.\nawesome-electron\nis a community-maintained list of useful example apps,\ntools and resources.\n\nSupported Versions\nThe latest three stable major versions are supported by the Electron team.\nFor example, if the latest release is 6.1.x, then the 5.0.x as well\nas the 4.2.x series are supported. We only support the latest minor release\nfor each stable release series. This means that in the case of a security fix\n6.1.x will receive the fix, but we will not release a new version of 6.0.x.\nThe latest stable release unilaterally receives all fixes from master,\nand the version prior to that receives the vast majority of those fixes\nas time and bandwidth warrants. The oldest supported release line will receive\nonly security fixes directly.\nAll supported release lines will accept external pull requests to backport\nfixes previously merged to master, though this may be on a case-by-case\nbasis for some older supported lines. All contested decisions around release\nline backports will be resolved by the Releases Working Group as an agenda item at their weekly meeting the week the backport PR is raised.\nWhen an API is changed or removed in a way that breaks existing functionality, the\nprevious functionality will be supported for a minimum of two major versions when\npossible before being removed. For example, if a function takes three arguments,\nand that number is reduced to two in major version 10, the three-argument version would\ncontinue to work until, at minimum, major version 12. Past the minimum two-version\nthreshold, we will attempt to support backwards compatibility beyond two versions\nuntil the maintainers feel the maintenance burden is too high to continue doing so.\n\nCurrently supported versions\n\n12.x.y\n11.x.y\n10.x.y\n\n\nEnd-of-life\nWhen a release branch reaches the end of its support cycle, the series\nwill be deprecated in NPM and a final end-of-support release will be\nmade. This release will add a warning to inform that an unsupported\nversion of Electron is in use.\nThese steps are to help app developers learn when a branch they're\nusing becomes unsupported, but without being excessively intrusive\nto end users.\nIf an application has exceptional circumstances and needs to stay\non an unsupported series of Electron, developers can silence the\nend-of-support warning by omitting the final release from the app's\npackage.json devDependencies. For example, since the 1-6-x series\nended with an end-of-support 1.6.18 release, developers could choose\nto stay in the 1-6-x series without warnings with devDependency of\n\"electron\": 1.6.0 - 1.6.17.\n\nSupported Platforms\nFollowing platforms are supported by Electron:\n\nmacOS\nOnly 64bit binaries are provided for macOS, and the minimum macOS version\nsupported is macOS 10.10 (Yosemite).\nNative support for Apple Silicon (arm64) devices was added in Electron 11.0.0.\n\nWindows\nWindows 7 and later are supported, older operating systems are not supported\n(and do not work).\nBoth ia32 (x86) and x64 (amd64) binaries are provided for Windows.\nNative support for Windows on Arm (arm64) devices was added in Electron 6.0.8..\nRunning apps packaged with previous versions is possible using the ia32 binary.\n\nLinux\nThe prebuilt binaries of Electron are built on Ubuntu 18.04.\nWhether the prebuilt binary can run on a distribution depends on whether the\ndistribution includes the libraries that Electron is linked to on the building\nplatform, so only Ubuntu 18.04 is guaranteed to work, but following platforms\nare also verified to be able to run the prebuilt binaries of Electron:\n\nUbuntu 14.04 and newer\nFedora 24 and newer\nDebian 8 and newer\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Electron Support",
"doc:support",
"tutorial:Electron Support",
"tutorial:support"
]
},
{
"objectID": "tutorial-testing",
"title": "Testing",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/development/testing.md",
"url": "https://electronjs.org/docs/development/testing",
"slug": "testing",
"body": "Testing\nWe aim to keep the code coverage of Electron high. We ask that all pull\nrequest not only pass all existing tests, but ideally also add new tests\nto cover changed code and new scenarios. Ensuring that we capture as\nmany code paths and use cases of Electron as possible ensures that we\nall ship apps with fewer bugs.\nThis repository comes with linting rules for both JavaScript and C++ –\nas well as unit and integration tests. To learn more about Electron's\ncoding style, please see the coding-style document.\n\nLinting\nTo ensure that your JavaScript is in compliance with the Electron coding\nstyle, run npm run lint-js, which will run standard against both\nElectron itself as well as the unit tests. If you are using an editor\nwith a plugin/addon system, you might want to use one of the many\nStandardJS addons to be informed of coding style\nviolations before you ever commit them.\nTo run standard with parameters, run npm run lint-js -- followed by\narguments you want passed to standard.\nTo ensure that your C++ is in compliance with the Electron coding style,\nrun npm run lint-cpp, which runs a cpplint script. We recommend that\nyou use clang-format and prepared a short tutorial.\nThere is not a lot of Python in this repository, but it too is governed\nby coding style rules. npm run lint-py will check all Python, using\npylint to do so.\n\nUnit Tests\nIf you are not using build-tools,\nensure that that name you have configured for your\nlocal build of Electron is one of Testing, Release, Default, Debug, or\nyou have set process.env.ELECTRON_OUT_DIR. Without these set, Electron will fail\nto perform some pre-testing steps.\nTo run all unit tests, run npm run test. The unit tests are an Electron\napp (surprise!) that can be found in the spec folder. Note that it has\nits own package.json and that its dependencies are therefore not defined\nin the top-level package.json.\nTo run only specific tests matching a pattern, run npm run test -- -g=PATTERN, replacing the PATTERN with a regex that matches the tests\nyou would like to run. As an example: If you want to run only IPC tests, you\nwould run npm run test -- -g ipc.\n\nTesting on Windows 10 devices\n\nExtra steps to run the unit test:\n\n\nVisual Studio 2019 must be installed.\n\n\nNode headers have to be compiled for your configuration.\nninja -C out\\Testing third_party\\electron_node:headers\n\n\n\nThe electron.lib has to be copied as node.lib.\ncd out\\Testing\nmkdir gen\\node_headers\\Release\ncopy electron.lib gen\\node_headers\\Release\\node.lib\n\n\n\n\nMissing fonts\nSome Windows 10 devices do not ship with the Meiryo font installed, which may cause a font fallback test to fail. To install Meiryo:\n\nPush the Windows key and search for Manage optional features.\nClick Add a feature.\nSelect Japanese Supplemental Fonts and click Install.\n\n\nPixel measurements\nSome tests which rely on precise pixel measurements may not work correctly on\ndevices with Hi-DPI screen settings due to floating point precision errors.\nTo run these tests correctly, make sure the device is set to 100% scaling.\nTo configure display scaling:\n\nPush the Windows key and search for Display settings.\nUnder Scale and layout, make sure that the device is set to 100%.\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Testing",
"doc:testing",
"tutorial:Testing",
"tutorial:testing"
]
},
{
"objectID": "tutorial-testing-on-headless-ci",
"title": "Testing on Headless CI Systems (Travis CI, Jenkins)",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/testing-on-headless-ci.md",
"url": "https://electronjs.org/docs/tutorial/testing-on-headless-ci",
"slug": "testing-on-headless-ci",
"body": "Testing on Headless CI Systems (Travis CI, Jenkins)\nBeing based on Chromium, Electron requires a display driver to function.\nIf Chromium can't find a display driver, Electron will fail to launch -\nand therefore not executing any of your tests, regardless of how you are running\nthem. Testing Electron-based apps on Travis, Circle, Jenkins or similar Systems\nrequires therefore a little bit of configuration. In essence, we need to use\na virtual display driver.\n\nConfiguring the Virtual Display Server\nFirst, install Xvfb.\nIt's a virtual framebuffer, implementing the X11 display server protocol -\nit performs all graphical operations in memory without showing any screen output,\nwhich is exactly what we need.\nThen, create a virtual Xvfb screen and export an environment variable\ncalled DISPLAY that points to it. Chromium in Electron will automatically look\nfor $DISPLAY, so no further configuration of your app is required.\nThis step can be automated with Anaïs Betts'\nxvfb-maybe: Prepend your test\ncommands with xvfb-maybe and the little tool will automatically configure\nXvfb, if required by the current system. On Windows or macOS, it will\ndo nothing.\n## On Windows or macOS, this invokes electron-mocha\n## On Linux, if we are in a headless environment, this will be equivalent\n## to xvfb-run electron-mocha ./test/*.js\nxvfb-maybe electron-mocha ./test/*.js\n\n\nTravis CI\nOn Travis, your .travis.yml should look roughly like this:\naddons:\n apt:\n packages:\n - xvfb\n\ninstall:\n - export DISPLAY=':99.0'\n - Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &\n\n\nJenkins\nFor Jenkins, a Xvfb plugin is available.\n\nCircle CI\nCircle CI is awesome and has Xvfb and $DISPLAY\nalready set up, so no further configuration is required.\n\nAppVeyor\nAppVeyor runs on Windows, supporting Selenium, Chromium, Electron and similar\ntools out of the box - no configuration is required.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Testing on Headless CI Systems (Travis CI, Jenkins)",
"doc:testing-on-headless-ci",
"tutorial:Testing on Headless CI Systems (Travis CI, Jenkins)",
"tutorial:testing-on-headless-ci"
]
},
{
"objectID": "tutorial-testing-widevine-cdm",
"title": "Testing Widevine CDM",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/testing-widevine-cdm.md",
"url": "https://electronjs.org/docs/tutorial/testing-widevine-cdm",
"slug": "testing-widevine-cdm",
"body": "Testing Widevine CDM\nIn Electron you can use the Widevine CDM library shipped with Chrome browser.\nWidevine Content Decryption Modules (CDMs) are how streaming services protect\ncontent using HTML5 video to web browsers without relying on an NPAPI plugin\nlike Flash or Silverlight. Widevine support is an alternative solution for\nstreaming services that currently rely on Silverlight for playback of\nDRM-protected video content. It will allow websites to show DRM-protected video\ncontent in Firefox without the use of NPAPI plugins. The Widevine CDM runs in an\nopen-source CDM sandbox providing better user security than NPAPI plugins.\n\nNote on VMP\nAs of Electron v1.8.0 (Chrome v59),\nthe below steps are may only be some of the necessary steps to enable Widevine;\nany app on or after that version intending to use the Widevine CDM may need to\nbe signed using a license obtained from Widevine\nitself.\nPer Widevine:\n\nChrome 59 (and later) includes support for Verified Media Path (VMP). VMP\nprovides a method to verify the authenticity of a device platform. For browser\ndeployments, this will provide an additional signal to determine if a\nbrowser-based implementation is reliable and secure.\nThe proxy integration guide has been updated with information about VMP and\nhow to issue licenses.\nWidevine recommends our browser-based integrations (vendors and browser-based\napplications) add support for VMP.\n\nTo enable video playback with this new restriction,\ncastLabs has created a\nfork that has implemented the\nnecessary changes to enable Widevine to be played in an Electron application if\none has obtained the necessary licenses from widevine.\n\nGetting the library\nOpen chrome://components/ in Chrome browser, find Widevine Content Decryption Module\nand make sure it is up to date, then you can find the library files from the\napplication directory.\n\nOn Windows\nThe library file widevinecdm.dll will be under\nProgram Files(x86)/Google/Chrome/Application/CHROME_VERSION/WidevineCdm/_platform_specific/win_(x86|x64)/\ndirectory.\n\nOn macOS\nThe library file libwidevinecdm.dylib will be under\n/Applications/Google Chrome.app/Contents/Versions/CHROME_VERSION/Google Chrome Framework.framework/Versions/A/Libraries/WidevineCdm/_platform_specific/mac_(x86|x64)/\ndirectory.\nNote: Make sure that chrome version used by Electron is greater than or\nequal to the min_chrome_version value of Chrome's widevine cdm component.\nThe value can be found in manifest.json under WidevineCdm directory.\n\nUsing the library\nAfter getting the library files, you should pass the path to the file\nwith --widevine-cdm-path command line switch, and the library's version\nwith --widevine-cdm-version switch. The command line switches have to be\npassed before the ready event of app module gets emitted.\nExample code:\nconst { app, BrowserWindow } = require('electron')\n\n// You have to pass the directory that contains widevine library here, it is\n// * `libwidevinecdm.dylib` on macOS,\n// * `widevinecdm.dll` on Windows.\napp.commandLine.appendSwitch('widevine-cdm-path', '/path/to/widevine_library')\n// The version of plugin can be got from `chrome://components` page in Chrome.\napp.commandLine.appendSwitch('widevine-cdm-version', '1.4.8.866')\n\nlet win = null\napp.whenReady().then(() => {\n win = new BrowserWindow()\n win.show()\n})\n\n\nVerifying Widevine CDM support\nTo verify whether widevine works, you can use following ways:\n\nOpen https://shaka-player-demo.appspot.com/ and load a manifest that uses\nWidevine.\nOpen http://www.dash-player.com/demo/drm-test-area/, check whether the page\nsays bitdash uses Widevine in your browser, then play the video.\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Testing Widevine CDM",
"doc:testing-widevine-cdm",
"tutorial:Testing Widevine CDM",
"tutorial:testing-widevine-cdm"
]
},
{
"objectID": "tutorial-updates",
"title": "Updating Applications",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/updates.md",
"url": "https://electronjs.org/docs/tutorial/updates",
"slug": "updates",
"body": "Updating Applications\nThere are several ways to update an Electron application. The easiest and\nofficially supported one is taking advantage of the built-in\nSquirrel framework and\nElectron's autoUpdater module.\n\nUsing update.electronjs.org\nThe Electron team maintains update.electronjs.org, a free and open-source\nwebservice that Electron apps can use to self-update. The service is designed\nfor Electron apps that meet the following criteria:\n\nApp runs on macOS or Windows\nApp has a public GitHub repository\nBuilds are published to GitHub Releases\nBuilds are code-signed\n\nThe easiest way to use this service is by installing update-electron-app,\na Node.js module preconfigured for use with update.electronjs.org.\nInstall the module:\nnpm install update-electron-app\n\nInvoke the updater from your app's main process file:\nrequire('update-electron-app')()\n\nBy default, this module will check for updates at app startup, then every ten\nminutes. When an update is found, it will automatically be downloaded in the background. When the download completes, a dialog is displayed allowing the user\nto restart the app.\nIf you need to customize your configuration, you can\npass options to update-electron-app\nor\nuse the update service directly.\n\nDeploying an Update Server\nIf you're developing a private Electron application, or if you're not\npublishing releases to GitHub Releases, it may be necessary to run your own\nupdate server.\nDepending on your needs, you can choose from one of these:\n\nHazel – Update server for private or open-source apps which can be\ndeployed for free on Now. It pulls from GitHub Releases\nand leverages the power of GitHub's CDN.\nNuts – Also uses GitHub Releases, but caches app\nupdates on disk and supports private repositories.\nelectron-release-server – Provides a dashboard for\nhandling releases and does not require releases to originate on GitHub.\nNucleus – A complete update server for Electron apps maintained by\nAtlassian. Supports multiple applications and channels; uses a static file store\nto minify server cost.\n\n\nImplementing Updates in Your App\nOnce you've deployed your update server, continue with importing the required\nmodules in your code. The following code might vary for different server\nsoftware, but it works like described when using\nHazel.\nImportant: Please ensure that the code below will only be executed in\nyour packaged app, and not in development. You can use\nelectron-is-dev to check for\nthe environment.\nconst { app, autoUpdater, dialog } = require('electron')\n\nNext, construct the URL of the update server and tell\nautoUpdater about it:\nconst server = 'https://your-deployment-url.com'\nconst url = `${server}/update/${process.platform}/${app.getVersion()}`\n\nautoUpdater.setFeedURL({ url })\n\nAs the final step, check for updates. The example below will check every minute:\nsetInterval(() => {\n autoUpdater.checkForUpdates()\n}, 60000)\n\nOnce your application is packaged,\nit will receive an update for each new\nGitHub Release that you\npublish.\n\nApplying Updates\nNow that you've configured the basic update mechanism for your application, you\nneed to ensure that the user will get notified when there's an update. This\ncan be achieved using the autoUpdater API\nevents:\nautoUpdater.on('update-downloaded', (event, releaseNotes, releaseName) => {\n const dialogOpts = {\n type: 'info',\n buttons: ['Restart', 'Later'],\n title: 'Application Update',\n message: process.platform === 'win32' ? releaseNotes : releaseName,\n detail: 'A new version has been downloaded. Restart the application to apply the updates.'\n }\n\n dialog.showMessageBox(dialogOpts).then((returnValue) => {\n if (returnValue.response === 0) autoUpdater.quitAndInstall()\n })\n})\n\nAlso make sure that errors are\nbeing handled. Here's an example\nfor logging them to stderr:\nautoUpdater.on('error', message => {\n console.error('There was a problem updating the application')\n console.error(message)\n})\n\n\nHandling Updates Manually\nBecause the requests made by Auto Update aren't under your direct control, you may find situations that are difficult to handle (such as if the update server is behind authentication). The url field does support files, which means that with some effort, you can sidestep the server-communication aspect of the process. Here's an example of how this could work.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Updating Applications",
"doc:updates",
"tutorial:Updating Applications",
"tutorial:updates"
]
},
{
"objectID": "tutorial-using-native-node-modules",
"title": "Using Native Node Modules",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/using-native-node-modules.md",
"url": "https://electronjs.org/docs/tutorial/using-native-node-modules",
"slug": "using-native-node-modules",
"body": "Using Native Node Modules\nNative Node.js modules are supported by Electron, but since Electron has a different\napplication binary interface (ABI) from a given Node.js binary (due to\ndifferences such as using Chromium's BoringSSL instead of OpenSSL), the native\nmodules you use will need to be recompiled for Electron. Otherwise,\nyou will get the following class of error when you try to run your app:\nError: The module '/path/to/native/module.node'\nwas compiled against a different Node.js version using\nNODE_MODULE_VERSION $XYZ. This version of Node.js requires\nNODE_MODULE_VERSION $ABC. Please try re-compiling or re-installing\nthe module (for instance, using `npm rebuild` or `npm install`).\n\n\nHow to install native modules\nThere are several different ways to install native modules:\n\nInstalling modules and rebuilding for Electron\nYou can install modules like other Node projects, and then rebuild the modules\nfor Electron with the electron-rebuild package. This\nmodule can automatically determine the version of Electron and handle the\nmanual steps of downloading headers and rebuilding native modules for your app.\nIf you are using Electron Forge, this tool is used automatically\nin both development mode and when making distributables.\nFor example, to install the standalone electron-rebuild tool and then rebuild\nmodules with it via the command line:\nnpm install --save-dev electron-rebuild\n\n# Every time you run \"npm install\", run this:\n./node_modules/.bin/electron-rebuild\n\n# If you have trouble on Windows, try:\n.\\node_modules\\.bin\\electron-rebuild.cmd\n\nFor more information on usage and integration with other tools such as Electron\nPackager, consult the project's README.\n\nUsing npm\nBy setting a few environment variables, you can use npm to install modules\ndirectly.\nFor example, to install all dependencies for Electron:\n# Electron's version.\nexport npm_config_target=1.2.3\n# The architecture of Electron, see https://electronjs.org/docs/tutorial/support#supported-platforms\n# for supported architectures.\nexport npm_config_arch=x64\nexport npm_config_target_arch=x64\n# Download headers for Electron.\nexport npm_config_disturl=https://electronjs.org/headers\n# Tell node-pre-gyp that we are building for Electron.\nexport npm_config_runtime=electron\n# Tell node-pre-gyp to build module from source code.\nexport npm_config_build_from_source=true\n# Install all dependencies, and store cache to ~/.electron-gyp.\nHOME=~/.electron-gyp npm install\n\n\nManually building for Electron\nIf you are a developer developing a native module and want to test it against\nElectron, you might want to rebuild the module for Electron manually. You can\nuse node-gyp directly to build for Electron:\ncd /path-to-module/\nHOME=~/.electron-gyp node-gyp rebuild --target=1.2.3 --arch=x64 --dist-url=https://electronjs.org/headers\n\n\nHOME=~/.electron-gyp changes where to find development headers.\n--target=1.2.3 is the version of Electron.\n--dist-url=... specifies where to download the headers.\n--arch=x64 says the module is built for a 64-bit system.\n\n\nManually building for a custom build of Electron\nTo compile native Node modules against a custom build of Electron that doesn't\nmatch a public release, instruct npm to use the version of Node you have bundled\nwith your custom build.\nnpm rebuild --nodedir=/path/to/electron/vendor/node\n\n\nTroubleshooting\nIf you installed a native module and found it was not working, you need to check\nthe following things:\n\nWhen in doubt, run electron-rebuild first.\nMake sure the native module is compatible with the target platform and\narchitecture for your Electron app.\nMake sure win_delay_load_hook is not set to false in the module's binding.gyp.\nAfter you upgrade Electron, you usually need to rebuild the modules.\n\n\nA note about win_delay_load_hook\nOn Windows, by default, node-gyp links native modules against node.dll.\nHowever, in Electron 4.x and higher, the symbols needed by native modules are\nexported by electron.exe, and there is no node.dll. In order to load native\nmodules on Windows, node-gyp installs a delay-load\nhook that triggers\nwhen the native module is loaded, and redirects the node.dll reference to use\nthe loading executable instead of looking for node.dll in the library search\npath (which would turn up nothing). As such, on Electron 4.x and higher,\n'win_delay_load_hook': 'true' is required to load native modules.\nIf you get an error like Module did not self-register, or The specified procedure could not be found, it may mean that the module you're trying to use\ndid not correctly include the delay-load hook. If the module is built with\nnode-gyp, ensure that the win_delay_load_hook variable is set to true in\nthe binding.gyp file, and isn't getting overridden anywhere. If the module\nis built with another system, you'll need to ensure that you build with a\ndelay-load hook installed in the main .node file. Your link.exe invocation\nshould look like this:\n link.exe /OUT:\"foo.node\" \"...\\node.lib\" delayimp.lib /DELAYLOAD:node.exe /DLL\n \"my_addon.obj\" \"win_delay_load_hook.obj\"\n\nIn particular, it's important that:\n\nyou link against node.lib from Electron and not Node. If you link against\nthe wrong node.lib you will get load-time errors when you require the\nmodule in Electron.\nyou include the flag /DELAYLOAD:node.exe. If the node.exe link is not\ndelayed, then the delay-load hook won't get a chance to fire and the node\nsymbols won't be correctly resolved.\nwin_delay_load_hook.obj is linked directly into the final DLL. If the hook\nis set up in a dependent DLL, it won't fire at the right time.\n\nSee node-gyp\nfor an example delay-load hook if you're implementing your own.\n\nModules that rely on prebuild\nprebuild provides a way to publish\nnative Node modules with prebuilt binaries for multiple versions of Node\nand Electron.\nIf the prebuild-powered module provide binaries for the usage in Electron,\nmake sure to omit --build-from-source and the npm_config_build_from_source\nenvironment variable in order to take full advantage of the prebuilt binaries.\n\nModules that rely on node-pre-gyp\nThe node-pre-gyp tool provides a way to deploy native Node\nmodules with prebuilt binaries, and many popular modules are using it.\nSometimes those modules work fine under Electron, but when there are no\nElectron-specific binaries available, you'll need to build from source.\nBecause of this, it is recommended to use electron-rebuild for these modules.\nIf you are following the npm way of installing modules, you'll need to pass\n--build-from-source to npm, or set the npm_config_build_from_source\nenvironment variable.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Using Native Node Modules",
"doc:using-native-node-modules",
"tutorial:Using Native Node Modules",
"tutorial:using-native-node-modules"
]
},
{
"objectID": "tutorial-using-pepper-flash-plugin",
"title": "Using Pepper Flash Plugin",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/using-pepper-flash-plugin.md",
"url": "https://electronjs.org/docs/tutorial/using-pepper-flash-plugin",
"slug": "using-pepper-flash-plugin",
"body": "Using Pepper Flash Plugin\nElectron no longer supports the Pepper Flash plugin, as Chrome has removed support.\nSee Chromium's Flash Roadmap for more\ndetails.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Using Pepper Flash Plugin",
"doc:using-pepper-flash-plugin",
"tutorial:Using Pepper Flash Plugin",
"tutorial:using-pepper-flash-plugin"
]
},
{
"objectID": "tutorial-using-selenium-and-webdriver",
"title": "Using Selenium and WebDriver",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/using-selenium-and-webdriver.md",
"url": "https://electronjs.org/docs/tutorial/using-selenium-and-webdriver",
"slug": "using-selenium-and-webdriver",
"body": "Using Selenium and WebDriver\nFrom ChromeDriver - WebDriver for Chrome:\n\nWebDriver is an open source tool for automated testing of web apps across many\nbrowsers. It provides capabilities for navigating to web pages, user input,\nJavaScript execution, and more. ChromeDriver is a standalone server which\nimplements WebDriver's wire protocol for Chromium. It is being developed by\nmembers of the Chromium and WebDriver teams.\n\n\nSetting up Spectron\nSpectron is the officially supported ChromeDriver testing framework\nfor Electron. It is built on top of WebdriverIO and\nhas helpers to access Electron APIs in your tests and bundles ChromeDriver.\n$ npm install --save-dev spectron\n\n// A simple test to verify a visible window is opened with a title\nconst Application = require('spectron').Application\nconst assert = require('assert')\n\nconst myApp = new Application({\n path: '/Applications/MyApp.app/Contents/MacOS/MyApp'\n})\n\nconst verifyWindowIsVisibleWithTitle = async (app) => {\n await app.start()\n try {\n // Check if the window is visible\n const isVisible = await app.browserWindow.isVisible()\n // Verify the window is visible\n assert.strictEqual(isVisible, true)\n // Get the window's title\n const title = await app.client.getTitle()\n // Verify the window's title\n assert.strictEqual(title, 'My App')\n } catch (error) {\n // Log any failures\n console.error('Test failed', error.message)\n }\n // Stop the application\n await app.stop()\n}\n\nverifyWindowIsVisibleWithTitle(myApp)\n\n\nSetting up with WebDriverJs\nWebDriverJs provides\na Node package for testing with web driver, we will use it as an example.\n\n1. Start ChromeDriver\nFirst you need to download the chromedriver binary, and run it:\n$ npm install electron-chromedriver\n$ ./node_modules/.bin/chromedriver\nStarting ChromeDriver (v2.10.291558) on port 9515\nOnly local connections are allowed.\n\nRemember the port number 9515, which will be used later\n\n2. Install WebDriverJS\n$ npm install selenium-webdriver\n\n\n3. Connect to ChromeDriver\nThe usage of selenium-webdriver with Electron is the same with\nupstream, except that you have to manually specify how to connect\nchrome driver and where to find Electron's binary:\nconst webdriver = require('selenium-webdriver')\n\nconst driver = new webdriver.Builder()\n // The \"9515\" is the port opened by chrome driver.\n .usingServer('http://localhost:9515')\n .withCapabilities({\n 'goog:chromeOptions': {\n // Here is the path to your Electron binary.\n binary: '/Path-to-Your-App.app/Contents/MacOS/Electron'\n }\n })\n .forBrowser('chrome') // note: use .forBrowser('electron') for selenium-webdriver <= 3.6.0\n .build()\n\ndriver.get('http://www.google.com')\ndriver.findElement(webdriver.By.name('q')).sendKeys('webdriver')\ndriver.findElement(webdriver.By.name('btnG')).click()\ndriver.wait(() => {\n return driver.getTitle().then((title) => {\n return title === 'webdriver - Google Search'\n })\n}, 1000)\n\ndriver.quit()\n\n\nSetting up with WebdriverIO\nWebdriverIO provides a Node package for testing with web\ndriver.\n\n1. Start ChromeDriver\nFirst you need to download the chromedriver binary, and run it:\n$ npm install electron-chromedriver\n$ ./node_modules/.bin/chromedriver --url-base=wd/hub --port=9515\nStarting ChromeDriver (v2.10.291558) on port 9515\nOnly local connections are allowed.\n\nRemember the port number 9515, which will be used later\n\n2. Install WebdriverIO\n$ npm install webdriverio\n\n\n3. Connect to chrome driver\nconst webdriverio = require('webdriverio')\nconst options = {\n host: 'localhost', // Use localhost as chrome driver server\n port: 9515, // \"9515\" is the port opened by chrome driver.\n desiredCapabilities: {\n browserName: 'chrome',\n 'goog:chromeOptions': {\n binary: '/Path-to-Your-App/electron', // Path to your Electron binary.\n args: [/* cli arguments */] // Optional, perhaps 'app=' + /path/to/your/app/\n }\n }\n}\n\nconst client = webdriverio.remote(options)\n\nclient\n .init()\n .url('http://google.com')\n .setValue('#q', 'webdriverio')\n .click('#btnG')\n .getTitle().then((title) => {\n console.log('Title was: ' + title)\n })\n .end()\n\n\nWorkflow\nTo test your application without rebuilding Electron,\nplace\nyour app source into Electron's resource directory.\nAlternatively, pass an argument to run with your Electron binary that points to\nyour app's folder. This eliminates the need to copy-paste your app into\nElectron's resource directory.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Using Selenium and WebDriver",
"doc:using-selenium-and-webdriver",
"tutorial:Using Selenium and WebDriver",
"tutorial:using-selenium-and-webdriver"
]
},
{
"objectID": "tutorial-v8-development",
"title": "V8 Development",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/development/v8-development.md",
"url": "https://electronjs.org/docs/development/v8-development",
"slug": "v8-development",
"body": "V8 Development\n\nA collection of resources for learning and using V8\n\n\nV8 Tracing\nV8 Profiler - Profiler combinations which are useful for profiling: --prof, --trace-ic, --trace-opt, --trace-deopt, --print-bytecode, --print-opt-code\nV8 Interpreter Design\nOptimizing compiler\nV8 GDB Debugging\n\nSee also Chromium Development",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:V8 Development",
"doc:v8-development",
"tutorial:V8 Development",
"tutorial:v8-development"
]
},
{
"objectID": "tutorial-web-embeds",
"title": "Web embeds",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/web-embeds.md",
"url": "https://electronjs.org/docs/tutorial/web-embeds",
"slug": "web-embeds",
"body": "Web embeds\n\nOverview\nIf you want to embed (third-party) web content in an Electron BrowserWindow,\nthere are three options available to you: <iframe> tags, <webview> tags,\nand BrowserViews. Each one offers slightly different functionality and is\nuseful in different situations. To help you choose between these, this guide\nexplains the differences and capabilities of each option.\n\nIframes\nIframes in Electron behave like iframes in regular browsers. An <iframe>\nelement in your page can show external web pages, provided that their\nContent Security Policy\nallows it. To limit the number of capabilities of a site in an <iframe> tag,\nit is recommended to use the sandbox attribute\nand only allow the capabilities you want to support.\n\nWebViews\n\nImportant Note:\nwe do not recommend you to use WebViews,\nas this tag undergoes dramatic architectural changes that may affect stability\nof your application. Consider switching to alternatives, like iframe and\nElectron's BrowserView, or an architecture that avoids embedded content\nby design.\n\nWebViews are based on Chromium's WebViews and are not\nexplicitly supported by Electron. We do not guarantee that the WebView API will\nremain available in future versions of Electron. To use <webview> tags, you\nwill need to set webviewTag to true in the webPreferences of your\nBrowserWindow.\nWebView is a custom element (<webview>) that will only work inside Electron.\nThey are implemented as an \"out-of-process iframe\". This means that all\ncommunication with the <webview> is done asynchronously using IPC. The\n<webview> element has many custom methods and events, similar to\nwebContents, that provide you with greater control over the content.\nCompared to an <iframe>, <webview> tends to be slightly slower but offers\nmuch greater control in loading and communicating with the third-party content\nand handling various events.\n\nBrowserViews\nBrowserViews are not a part of the DOM - instead,\nthey are created in and controlled by your Main process. They are simply\nanother layer of web content on top of your existing window. This means\nthat they are completely separate from your own BrowserWindow content and\ntheir position is not controlled by the DOM or CSS. Instead, it is controlled\nby setting the bounds in the Main process.\nBrowserViews offer the greatest control over their contents, since they\nimplement the webContents similarly to how the BrowserWindow does it.\nHowever, as BrowserViews are not a part of your DOM, but are rather overlaid\non top of them, you will have to manage their position manually.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Web embeds",
"doc:web-embeds",
"tutorial:Web embeds",
"tutorial:web-embeds"
]
},
{
"objectID": "tutorial-windows-arm",
"title": "Windows 10 on Arm",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/windows-arm.md",
"url": "https://electronjs.org/docs/tutorial/windows-arm",
"slug": "windows-arm",
"body": "Windows 10 on Arm\nIf your app runs with Electron 6.0.8 or later, you can now build it for Windows 10 on Arm. This considerably improves performance, but requires recompilation of any native modules used in your app. It may also require small fixups to your build and packaging scripts.\n\nRunning a basic app\nIf your app doesn't use any native modules, then it's really easy to create an Arm version of your app.\n\nMake sure that your app's node_modules directory is empty.\nUsing a Command Prompt, run set npm_config_arch=arm64 before running npm install/yarn install as usual.\nIf you have Electron installed as a development dependency, npm will download and unpack the arm64 version. You can then package and distribute your app as normal.\n\n\nGeneral considerations\n\nArchitecture-specific code\nLots of Windows-specific code contains if... else logic that selects between either the x64 or x86 architectures.\nif (process.arch === 'x64') {\n // Do 64-bit thing...\n} else {\n // Do 32-bit thing...\n}\n\nIf you want to target arm64, logic like this will typically select the wrong architecture, so carefully check your application and build scripts for conditions like this. In custom build and packaging scripts, you should always check the value of npm_config_arch in the environment, rather than relying on the current process arch.\n\nNative modules\nIf you use native modules, you must make sure that they compile against v142 of the MSVC compiler (provided in Visual Studio 2017). You must also check that any pre-built .dll or .lib files provided or referenced by the native module are available for Windows on Arm.\n\nTesting your app\nTo test your app, use a Windows on Arm device running Windows 10 (version 1903 or later). Make sure that you copy your application over to the target device - Chromium's sandbox will not work correctly when loading your application assets from a network location.\n\nDevelopment prerequisites\n\nNode.js/node-gyp\nNode.js v12.9.0 or later is recommended. If updating to a new version of Node is undesirable, you can instead update npm's copy of node-gyp manually to version 5.0.2 or later, which contains the required changes to compile native modules for Arm.\n\nVisual Studio 2017\nVisual Studio 2017 (any edition) is required for cross-compiling native modules. You can download Visual Studio Community 2017 via Microsoft's Visual Studio Dev Essentials program. After installation, you can add the Arm-specific components by running the following from a Command Prompt:\nvs_installer.exe ^\n--add Microsoft.VisualStudio.Workload.NativeDesktop ^\n--add Microsoft.VisualStudio.Component.VC.ATLMFC ^\n--add Microsoft.VisualStudio.Component.VC.Tools.ARM64 ^\n--add Microsoft.VisualStudio.Component.VC.MFC.ARM64 ^\n--includeRecommended\n\n\nCreating a cross-compilation command prompt\nSetting npm_config_arch=arm64 in the environment creates the correct arm64 .obj files, but the standard Developer Command Prompt for VS 2017 will use the x64 linker. To fix this:\n\nDuplicate the x64_x86 Cross Tools Command Prompt for VS 2017 shortcut (e.g. by locating it in the start menu, right clicking, selecting Open File Location, copying and pasting) to somewhere convenient.\nRight click the new shortcut and choose Properties.\nChange the Target field to read vcvarsamd64_arm64.bat at the end instead of vcvarsamd64_x86.bat.\n\nIf done successfully, the command prompt should print something similar to this on startup:\n**********************************************************************\n** Visual Studio 2017 Developer Command Prompt v15.9.15\n** Copyright (c) 2017 Microsoft Corporation\n**********************************************************************\n[vcvarsall.bat] Environment initialized for: 'x64_arm64'\n\nIf you want to develop your application directly on a Windows on Arm device, substitute vcvarsx86_arm64.bat in Target so that cross-compilation can happen with the device's x86 emulation.\n\nLinking against the correct node.lib\nBy default, node-gyp unpacks Electron's node headers and downloads the x86 and x64 versions of node.lib into %APPDATA%\\..\\Local\\node-gyp\\Cache, but it does not download the arm64 version (a fix for this is in development.) To fix this:\n\nDownload the arm64 node.lib from https://electronjs.org/headers/v6.0.9/win-arm64/node.lib\nMove it to %APPDATA%\\..\\Local\\node-gyp\\Cache\\6.0.9\\arm64\\node.lib\n\nSubstitute 6.0.9 for the version you're using.\n\nCross-compiling native modules\nAfter completing all of the above, open your cross-compilation command prompt and run set npm_config_arch=arm64. Then use npm install to build your project as normal. As with cross-compiling x86 modules, you may need to remove node_modules to force recompilation of native modules if they were previously compiled for another architecture.\n\nDebugging native modules\nDebugging native modules can be done with Visual Studio 2017 (running on your development machine) and corresponding Visual Studio Remote Debugger running on the target device. To debug:\n\nLaunch your app .exe on the target device via the Command Prompt (passing --inspect-brk to pause it before any native modules are loaded).\nLaunch Visual Studio 2017 on your development machine.\nConnect to the target device by selecting Debug > Attach to Process... and enter the device's IP address and the port number displayed by the Visual Studio Remote Debugger tool.\nClick Refresh and select the appropriate Electron process to attach.\nYou may need to make sure that any symbols for native modules in your app are loaded correctly. To configure this, head to Debug > Options... in Visual Studio 2017, and add the folders containing your .pdb symbols under Debugging > Symbols.\nOnce attached, set any appropriate breakpoints and resume JavaScript execution using Chrome's remote tools for Node.\n\n\nGetting additional help\nIf you encounter a problem with this documentation, or if your app works when compiled for x86 but not for arm64, please file an issue with \"Windows on Arm\" in the title.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Windows 10 on Arm",
"doc:windows-arm",
"tutorial:Windows 10 on Arm",
"tutorial:windows-arm"
]
},
{
"objectID": "tutorial-windows-store-guide",
"title": "Windows Store Guide",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/windows-store-guide.md",
"url": "https://electronjs.org/docs/tutorial/windows-store-guide",
"slug": "windows-store-guide",
"body": "Windows Store Guide\nWith Windows 10, the good old win32 executable got a new sibling: The Universal\nWindows Platform. The new .appx format does not only enable a number of new\npowerful APIs like Cortana or Push Notifications, but through the Windows Store,\nalso simplifies installation and updating.\nMicrosoft developed a tool that compiles Electron apps as .appx packages,\nenabling developers to use some of the goodies found in the new application\nmodel. This guide explains how to use it - and what the capabilities and\nlimitations of an Electron AppX package are.\n\nBackground and Requirements\nWindows 10 \"Anniversary Update\" is able to run win32 .exe binaries by\nlaunching them together with a virtualized filesystem and registry. Both are\ncreated during compilation by running app and installer inside a Windows\nContainer, allowing Windows to identify exactly which modifications to the\noperating system are done during installation. Pairing the executable with a\nvirtual filesystem and a virtual registry allows Windows to enable one-click\ninstallation and uninstallation.\nIn addition, the exe is launched inside the appx model - meaning that it can use\nmany of the APIs available to the Universal Windows Platform. To gain even more\ncapabilities, an Electron app can pair up with an invisible UWP background task\nlaunched together with the exe - sort of launched as a sidekick to run tasks\nin the background, receive push notifications, or to communicate with other UWP\napplications.\nTo compile any existing Electron app, ensure that you have the following\nrequirements:\n\nWindows 10 with Anniversary Update (released August 2nd, 2016)\nThe Windows 10 SDK, downloadable here\nAt least Node 4 (to check, run node -v)\n\nThen, go and install the electron-windows-store CLI:\nnpm install -g electron-windows-store\n\n\nStep 1: Package Your Electron Application\nPackage the application using electron-packager (or a similar tool).\nMake sure to remove node_modules that you don't need in your final application, since\nany module you don't actually need will increase your application's size.\nThe output should look roughly like this:\n├── Ghost.exe\n├── LICENSE\n├── content_resources_200_percent.pak\n├── content_shell.pak\n├── d3dcompiler_47.dll\n├── ffmpeg.dll\n├── icudtl.dat\n├── libEGL.dll\n├── libGLESv2.dll\n├── locales\n│   ├── am.pak\n│   ├── ar.pak\n│   ├── [...]\n├── node.dll\n├── resources\n│   └── app.asar\n├── v8_context_snapshot.bin\n├── squirrel.exe\n└── ui_resources_200_percent.pak\n\n\nStep 2: Running electron-windows-store\nFrom an elevated PowerShell (run it \"as Administrator\"), run\nelectron-windows-store with the required parameters, passing both the input\nand output directories, the app's name and version, and confirmation that\nnode_modules should be flattened.\nelectron-windows-store `\n --input-directory C:\\myelectronapp `\n --output-directory C:\\output\\myelectronapp `\n --package-version 1.0.0.0 `\n --package-name myelectronapp\n\nOnce executed, the tool goes to work: It accepts your Electron app as an input,\nflattening the node_modules. Then, it archives your application as app.zip.\nUsing an installer and a Windows Container, the tool creates an \"expanded\" AppX\npackage - including the Windows Application Manifest (AppXManifest.xml) as\nwell as the virtual file system and the virtual registry inside your output\nfolder.\nOnce the expanded AppX files are created, the tool uses the Windows App Packager\n(MakeAppx.exe) to create a single-file AppX package from those files on disk.\nFinally, the tool can be used to create a trusted certificate on your computer\nto sign the new AppX package. With the signed AppX package, the CLI can also\nautomatically install the package on your machine.\n\nStep 3: Using the AppX Package\nIn order to run your package, your users will need Windows 10 with the so-called\n\"Anniversary Update\" - details on how to update Windows can be found here.\nIn opposition to traditional UWP apps, packaged apps currently need to undergo a\nmanual verification process, for which you can apply here.\nIn the meantime, all users will be able to install your package by double-clicking it,\nso a submission to the store might not be necessary if you're looking for an\neasier installation method. In managed environments (usually enterprises), the\nAdd-AppxPackage PowerShell Cmdlet can be used to install it in an automated fashion.\nAnother important limitation is that the compiled AppX package still contains a\nwin32 executable - and will therefore not run on Xbox, HoloLens, or Phones.\n\nOptional: Add UWP Features using a BackgroundTask\nYou can pair your Electron app up with an invisible UWP background task that\ngets to make full use of Windows 10 features - like push notifications,\nCortana integration, or live tiles.\nTo check out how an Electron app that uses a background task to send toast\nnotifications and live tiles, check out the Microsoft-provided sample.\n\nOptional: Convert using Container Virtualization\nTo generate the AppX package, the electron-windows-store CLI uses a template\nthat should work for most Electron apps. However, if you are using a custom\ninstaller, or should you experience any trouble with the generated package, you\ncan attempt to create a package using compilation with a Windows Container - in\nthat mode, the CLI will install and run your application in blank Windows Container\nto determine what modifications your application is exactly doing to the operating\nsystem.\nBefore running the CLI for the first time, you will have to setup the \"Windows Desktop App\nConverter\". This will take a few minutes, but don't worry - you only have to do\nthis once. Download and Desktop App Converter from here.\nYou will receive two files: DesktopAppConverter.zip and BaseImage-14316.wim.\n\nUnzip DesktopAppConverter.zip. From an elevated PowerShell (opened with\n\"run as Administrator\", ensure that your systems execution policy allows us to\nrun everything we intend to run by calling Set-ExecutionPolicy bypass.\nThen, run the installation of the Desktop App Converter, passing in the\nlocation of the Windows base Image (downloaded as BaseImage-14316.wim), by\ncalling .\\DesktopAppConverter.ps1 -Setup -BaseImage .\\BaseImage-14316.wim.\nIf running the above command prompts you for a reboot, please restart your\nmachine and run the above command again after a successful restart.\n\nOnce installation succeeded, you can move on to compiling your Electron app.",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Windows Store Guide",
"doc:windows-store-guide",
"tutorial:Windows Store Guide",
"tutorial:windows-store-guide"
]
},
{
"objectID": "tutorial-windows-taskbar",
"title": "Windows Taskbar",
"githubUrl": "https://github.com/electron/electron/tree/master/docs/tutorial/windows-taskbar.md",
"url": "https://electronjs.org/docs/tutorial/windows-taskbar",
"slug": "windows-taskbar",
"body": "Windows Taskbar\n\nOverview\nElectron has APIs to configure the app's icon in the Windows taskbar. This API\nsupports both Windows-only features like creation of a JumpList,\ncustom thumbnails and toolbars,\nicon overlays, and the so-called\n\"Flash Frame\" effect, and cross-platform features\nlike recent documents and\napplication progress.\n\nJumpList\nWindows allows apps to define a custom context menu that shows up when users\nright-click the app's icon in the taskbar. That context menu is called\nJumpList. You specify custom actions in the Tasks category of JumpList,\nas quoted from MSDN:\n\nApplications define tasks based on both the program's features and the key\nthings a user is expected to do with them. Tasks should be context-free, in\nthat the application does not need to be running for them to work. They\nshould also be the statistically most common actions that a normal user would\nperform in an application, such as compose an email message or open the\ncalendar in a mail program, create a new document in a word processor, launch\nan application in a certain mode, or launch one of its subcommands. An\napplication should not clutter the menu with advanced features that standard\nusers won't need or one-time actions such as registration. Do not use tasks\nfor promotional items such as upgrades or special offers.\nIt is strongly recommended that the task list be static. It should remain the\nsame regardless of the state or status of the application. While it is\npossible to vary the list dynamically, you should consider that this could\nconfuse the user who does not expect that portion of the destination list to\nchange.\n\n\n\nNOTE: The screenshot above is an example of general tasks of\nInternet Explorer\n\nUnlike the dock menu in macOS which is a real menu, user tasks in Windows work\nlike application shortcuts. For example, when a user clicks a task, the program\nwill be executed with specified arguments.\nTo set user tasks for your application, you can use\napp.setUserTasks API.\n\nExamples\n\nSet user tasks\nStarting with a working application from the\nQuick Start Guide, update the main.js file with the\nfollowing lines:\nconst { app } = require('electron')\n\napp.setUserTasks([\n {\n program: process.execPath,\n arguments: '--new-window',\n iconPath: process.execPath,\n iconIndex: 0,\n title: 'New Window',\n description: 'Create a new window'\n }\n])\n\n\nClear tasks list\nTo clear your tasks list, you need to call app.setUserTasks with an empty\narray in the main.js file.\nconst { app } = require('electron')\n\napp.setUserTasks([])\n\n\nNOTE: The user tasks will still be displayed even after closing your\napplication, so the icon and program path specified for a task should exist until your application is uninstalled.\n\n\nThumbnail Toolbars\nOn Windows, you can add a thumbnail toolbar with specified buttons to a taskbar\nlayout of an application window. It provides users with a way to access a\nparticular window's command without restoring or activating the window.\nAs quoted from MSDN:\n\nThis toolbar is the familiar standard toolbar common control. It has a\nmaximum of seven buttons. Each button's ID, image, tooltip, and state are defined\nin a structure, which is then passed to the taskbar. The application can show,\nenable, disable, or hide buttons from the thumbnail toolbar as required by its\ncurrent state.\nFor example, Windows Media Player might offer standard media transport controls\nsuch as play, pause, mute, and stop.\n\n\n\nNOTE: The screenshot above is an example of thumbnail toolbar of Windows\nMedia Player\n\nTo set thumbnail toolbar in your application, you need to use\nBrowserWindow.setThumbarButtons\n\nExamples\n\nSet thumbnail toolbar\nStarting with a working application from the\nQuick Start Guide, update the main.js file with the\nfollowing lines:\nconst { BrowserWindow } = require('electron')\nconst path = require('path')\n\nconst win = new BrowserWindow()\n\nwin.setThumbarButtons([\n {\n tooltip: 'button1',\n icon: path.join(__dirname, 'button1.png'),\n click () { console.log('button1 clicked') }\n }, {\n tooltip: 'button2',\n icon: path.join(__dirname, 'button2.png'),\n flags: ['enabled', 'dismissonclick'],\n click () { console.log('button2 clicked.') }\n }\n])\n\n\nClear thumbnail toolbar\nTo clear thumbnail toolbar buttons, you need to call\nBrowserWindow.setThumbarButtons with an empty array in the main.js file.\nconst { BrowserWindow } = require('electron')\n\nconst win = new BrowserWindow()\nwin.setThumbarButtons([])\n\n\nIcon Overlays in Taskbar\nOn Windows, a taskbar button can use a small overlay to display application\nstatus.\nAs quoted from MSDN:\n\nIcon overlays serve as a contextual notification of status, and are intended\nto negate the need for a separate notification area status icon to communicate\nthat information to the user. For instance, the new mail status in Microsoft\nOutlook, currently shown in the notification area, can now be indicated\nthrough an overlay on the taskbar button. Again, you must decide during your\ndevelopment cycle which method is best for your application. Overlay icons are\nintended to supply important, long-standing status or notifications such as\nnetwork status, messenger status, or new mail. The user should not be\npresented with constantly changing overlays or animations.\n\n\n\nNOTE: The screenshot above is an example of overlay on a taskbar button\n\nTo set the overlay icon for a window, you need to use the\nBrowserWindow.setOverlayIcon API.\n\nExample\nStarting with a working application from the\nQuick Start Guide, update the main.js file with the\nfollowing lines:\nconst { BrowserWindow } = require('electron')\n\nconst win = new BrowserWindow()\n\nwin.setOverlayIcon('path/to/overlay.png', 'Description for overlay')\n\n\nFlash Frame\nOn Windows, you can highlight the taskbar button to get the user's attention.\nThis is similar to bouncing the dock icon in macOS.\nAs quoted from MSDN:\n\nTypically, a window is flashed to inform the user that the window requires\nattention but that it does not currently have the keyboard focus.\n\nTo flash the BrowserWindow taskbar button, you need to use the\nBrowserWindow.flashFrame API.\n\nExample\nStarting with a working application from the\nQuick Start Guide, update the main.js file with the\nfollowing lines:\nconst { BrowserWindow } = require('electron')\n\nconst win = new BrowserWindow()\n\nwin.once('focus', () => win.flashFrame(false))\nwin.flashFrame(true)\n\n\nNOTE: Don't forget to call win.flashFrame(false) to turn off the flash.\nIn the above example, it is called when the window comes into focus,\nbut you might use a timeout or some other event to disable it.\n",
"keyValuePairs": [
"is:doc",
"is:tutorial",
"doc:Windows Taskbar",
"doc:windows-taskbar",
"tutorial:Windows Taskbar",
"tutorial:windows-taskbar"
]
}
]
}