Shortcuts in Electron.js —also called keyboard shortcuts, accelerators, or directly hotkeys— are another feature closely linked to Menus in Electron.js that allow actions to be executed without relying on the mouse. In any modern desktop application, from VSCode to Photoshop, shortcuts are part of the natural workflow… and when we create apps with Electron, we can not only replicate them: we can take them further, because we have control over both the main process and the renderer.
Shortcuts are usually used for two things:
- executing quick actions inside the window (for example, CommandOrControl+S to save), and
- triggering actions even when the app is not in focus, which is where globalShortcut comes into play.
Local vs global (when to use each)
Local Shortcuts
They work only if the app window is active. They are perfect for:
- saving, opening, reloading
- menu actions
- internal UX of the editor, viewer, dashboard…
Global Shortcuts
They work even if the app is minimized. Perfect for:
- launching quick capturers
- opening an auxiliary window
- activating tools (snippets, searchers, etc.)
Creating local shortcuts with "accelerator"
The globalShortcut module can register (or unregister) a global keyboard shortcut with the operating system so that you can customize operations for various shortcuts to perform specific functions in each case; for example, the famous combination of Control/Command + S to save the application state is easy to capture in Electron.js:
const { globalShortcut } = require('electron')
globalShortcut.register('CommandOrControl+S', () => {
// TO DO
});To unregister or de-register a combination:
globalShortcut.unregister('CommandOrControl+X')To unregister or de-register all shortcuts:
globalShortcut.unregisterAll()From the menu in Electron.js, we can specify a property called accelerator with which we can also specify keyboard shortcuts; for example:
menu.js
const { app, ipcMain, Menu, shell, BrowserWindow, globalShortcut } = require('electron')
const { open_file, save_file } = require("./editor-options")
const template = [
***
{
label: 'File',
submenu: [
{
label: "Save",
accelerator: 'CommandOrControl+Shift+S',
click() {
const win = BrowserWindow.getFocusedWindow()
win.webContents.send('editorchannel', 'file-save')
}
},
},
***
]Cross-platform Accelerators
Electron automatically translates these combinations:
- CommandOrControl → Cmd on macOS, Ctrl on Windows and Linux
- Alt → Option on macOS, Alt on Windows/Linux
- Super/Meta → Cmd (macOS) and Windows key on Windows
⚡ Registering global shortcuts with globalShortcut
Now we enter "powerful" territory: capturing a combination even if your app is minimized or in the background.
When I started using it, the first thing I tried was to register a classic shortcut:
const { app, globalShortcut } = require('electron')
app.whenReady().then(() => {
globalShortcut.register('CommandOrControl+S', () => {
console.log('Atajo global capturado')
})
})And yes: it worked exactly as I expected.
Registering, unregistering and clearing shortcuts
globalShortcut.register('CommandOrControl+K', () => {
console.log('Shortcut global K ejecutado')
})
globalShortcut.unregister('CommandOrControl+K')
globalShortcut.unregisterAll()A detail: when I work with multiple windows or modes (editing mode, preview mode…), I always unregister the shortcuts I no longer need to avoid phantom behaviors.
Best Practices
- Register them only after app.whenReady.
- Unregister them when closing the window.
- Avoid collisions with system shortcuts (Ctrl+Space, Command+Space…).
⌨️ Shortcuts from the renderer: keyup/keydown and before-input-event
If you need to capture keys inside the WebView, you can do it directly in the DOM:
window.addEventListener('keyup', (event) => { console.log('Key pressed:', event.key) }, true)I use this when I need more specific combinations within an editor or panel.
Intercepting keys in the main process
For cases where I don't want a shortcut to appear as an accelerator, I use:
win.webContents.on('before-input-event', (event, input) => {
if (input.control && input.key.toLowerCase() === 'i') {
console.log('Control+I intercept')
event.preventDefault()
}
})This gives a lot of control without "contaminating" the menu.
️ How to handle cross-platform shortcuts
The most important thing:
✔ Modifiers
macOS Windows / Linux
Command —
Control Control
CommandOrControl Cmd
Alt Alt
Option —
Super/Meta Cmd
❗ Common errors and how to solve them
1. The shortcut does not execute
Typical causes:
- You did not call app.whenReady()
- An identical shortcut was already assigned by the system
- It was not registered due to a silent error (use globalShortcut.isRegistered)
2. Collisions with the operating system
Shortcuts like:
- Cmd+Space
- Ctrl+Alt+Delete
are blocked. Always avoid them.
3. Unsupported keys
Some special keys do not work as accelerators (depending on the platform).
Conclusion
Creating shortcuts in Electron.js is simple once you understand the 3 approaches:
- accelerator → Menu and in-app shortcuts
- globalShortcut → Global shortcuts even if the app is minimized
- keyup/before-input-event → Fine-grained captures in the renderer or main
When I combine these methods in my projects, I achieve a fluid experience: clear shortcuts, global when I need them, and fully adapted to each platform.
❓ Frequently Asked Questions
- Can I register different shortcuts per window?
- Yes, globalShortcut are global, but local ones depend on the menu associated with each window.
- How do I prevent a shortcut from accidentally triggering actions?
- By unregistering it when you change mode or window.
- Can I check if a shortcut is already in use?
- You can use globalShortcut.isRegistered('<combo>').
We continue with events in Electron.js
I agree to receive announcements of interest about this Blog.
The globalShortcut module can register (or override) a global keyboard shortcut with the operating system; let's see how to use it and recommendations for its use in Windows and MacOS.