Electron 44 dropped on August 25 and it rewrote the clipboard. Every synchronous call is now async, the renderer process can no longer touch the clipboard module at all, and eight convenience methods are gone — replaced by a MIME-type-based ClipboardItem API that mirrors the W3C web standard. If your app uses clipboard.readText(), writeHTML(), readImage(), or calls any clipboard method from a renderer process, it breaks silently or loudly on Electron 44. VS Code, Slack, Discord, Claude Desktop — the entire Electron ecosystem is sitting on this migration.
The Core Change: Everything Is Async Now #
The biggest shift is the easiest to describe: every clipboard method now returns a Promise. There are no exceptions. readText(), writeText(), read(), write(), and has() are all async. The dangerous part is that calling clipboard.readText() without await does not throw — it returns a Promise object. Assign that to a variable and use it as a string, and you get silent corruption.
The migration for this specific change is mechanical:
// Before — Electron 43
const text = clipboard.readText();
clipboard.writeText('hello world');
// After — Electron 44
const text = await clipboard.readText();
await clipboard.writeText('hello world');
Run a search across your codebase for every call to a clipboard method and add await. Any function that makes a clipboard call must become async as well. This ripples, but it is mechanical work.
Renderer Process Clipboard Access Is Gone #
This is the real headache. The clipboard module is no longer available in renderer processes. Calling require('electron').clipboard in a renderer returns undefined in Electron 44. The Electron team’s reasoning is sound — removing direct clipboard access from renderers closes a class of XSS vulnerabilities where malicious web content could exfiltrate clipboard data. The security argument wins. But it means a non-trivial refactor for any app that uses clipboard from the renderer.
For basic text operations in a renderer, use the web platform directly:
// In renderer — no Electron import needed
const text = await navigator.clipboard.readText();
await navigator.clipboard.writeText('hello world');
For anything beyond plain text — custom MIME types, images, RTF — you need the contextBridge pattern:
// preload.js
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronClipboard', {
readText: () => ipcRenderer.invoke('clipboard:readText'),
writeText: (text) => ipcRenderer.invoke('clipboard:writeText', text),
read: () => ipcRenderer.invoke('clipboard:read'),
});
// main.js
const { ipcMain, clipboard } = require('electron');
ipcMain.handle('clipboard:readText', () => clipboard.readText());
ipcMain.handle('clipboard:writeText', (_, text) => clipboard.writeText(text));
ipcMain.handle('clipboard:read', () => clipboard.read());
// In renderer (after migration)
const text = await window.electronClipboard.readText();
One note on security: do not expose the full clipboard API through contextBridge if your renderer loads untrusted web content. Expose only the minimum your app actually needs.
Eight Convenience Methods Are Gone #
Along with the async shift, Electron 44 removes the narrow helper methods in favor of the generic MIME-type-based read() and write(). Here is what disappeared and how to replace each:
- readImage() / writeImage() — use
read()and look forimage/pngorimage/jpegin item types - readHTML() / writeHTML() — use
text/htmlas the MIME type withClipboardItem - readRTF() / writeRTF() — use
text/rtf - availableFormats() — call
clipboard.read()and iterate the.typesarray on returned items
Writing HTML now looks like this:
const { clipboard, ClipboardItem } = require('electron');
// Before
clipboard.writeHTML('<b>Bold text</b>');
// After
await clipboard.write([
new ClipboardItem({ 'text/html': '<b>Bold text</b>' })
]);
On Linux, the selection clipboard has moved to a sub-namespace: clipboard.selection.readText() instead of clipboard.readText('selection').
Platform Drops: Check Your Build Matrix #
Three platforms are out as of Electron 44. Windows x86 (32-bit), Linux ARMv7, and macOS 12 (Monterey) are no longer supported. Electron 43 keeps these alive until January 2027 end-of-life, so teams with users on these platforms have a runway — but it ends. Update your CI build matrix and user-facing system requirements now, before someone discovers the failure in production. Electron Forge already patched its build tooling in PR #4377; if you use a custom build script, update it manually.
The openAsHidden option is also gone from app.setLoginItemSettings() — it only ever worked on macOS 12, which is now unsupported. The app.isUnityRunning() method is removed on Linux as Unity desktop environment support is dropped.
What Is Actually Good in This Release #
Not everything is migration work. Electron 44 adds windowStatePersistence, which replaces what most apps were doing manually with electron-window-state or equivalent boilerplate:
new BrowserWindow({
name: 'main-window', // required — must be unique per window
windowStatePersistence: true // saves position, size, display across launches
});
The release also ships net.WebSocket — a WHATWG-compatible WebSocket client for the main process that routes through Chromium’s network stack. Previously, main-process WebSocket required either a Node.js library or a round-trip through the renderer. Linux gets a ~37 MB distribution size reduction, badge counts and progress bars no longer require libunity, and win.setOpacity() finally lands on Linux.
How to Upgrade #
Start in Electron Fiddle or a feature branch — do not upgrade in production cold. Run npm install electron@latest, then use the official breaking changes doc as your checklist. The clipboard migration is the bulk of the work; everything else is mechanical. Once your tests pass locally, verify with a staging build before shipping to users. The new clipboard API reference has complete method signatures and the Electron 44 release post covers the full changelog.
Electron 44 is Chromium 152, Node 24.18, and a security-forward API design. The clipboard migration is tedious, but the direction is correct — it aligns with the web platform and closes real attack surface. Do it once and move on.