|
| 1 | +--- |
| 2 | +title: 'Tech Talk: How Electron went Wayland-native (and how it affects your apps)' |
| 3 | +date: 2026-03-10T00:00:00.000Z |
| 4 | +authors: |
| 5 | + - name: mitchchn |
| 6 | + url: 'https://github.com/mitchchn' |
| 7 | + image_url: 'https://github.com/mitchchn.png?size=96' |
| 8 | +slug: tech-talk-wayland |
| 9 | +tags: [techtalk, internals] |
| 10 | +--- |
| 11 | + |
| 12 | +_Tech talks are a new blog post series where we share glimpses into our work on Electron. If you find this work interesting, please consider [contributing](https://github.com/electron/electron/)!_ |
| 13 | + |
| 14 | +When Electron switched to the [Wayland](https://wayland.freedesktop.org/) display protocol last fall, most people didn't even notice. |
| 15 | + |
| 16 | +That's likely a good thing. Wayland is the modern successor to the X11 framework, which Linux has used to display graphical interfaces for decades. Major Linux distributions have already adopted Wayland for their default desktop sessions, and both the KDE Plasma and GNOME desktop environments are in the process of [dropping X11 support](https://blogs.kde.org/2025/11/26/going-all-in-on-a-wayland-future/) [completely](https://www.phoronix.com/news/GNOME-50-Alpha/). If anything, Electron was a little late to the party. |
| 17 | + |
| 18 | +But a platform migration isn't complete without apps, and the Linux app ecosystem went through a rapid Wayland transition last August after Chromium [turned on Wayland support by default](https://chromium-review.googlesource.com/c/chromium/src/+/6819616). That move brought along the Electron framework and dozens of Linux desktop apps built on top of it. |
| 19 | + |
| 20 | +## The third impact: Electron goes Wayland-native |
| 21 | + |
| 22 | +Wayland is supported out of the box in [Electron 38.2](https://releases.electronjs.org/release/v38.2.0) and newer. As long as your desktop is using Wayland and your apps are up-to-date, it just works. (If you were previously launching your Electron apps with very long commands like `CONFUSING_OZONE_VARIABLE --ozone-platform=wayland`, you no longer need to do that.) |
| 23 | + |
| 24 | +This change was only possible because the Chromium and Electron projects had been [working on Wayland support](https://github.com/electron/electron/pull/26022) for more than half a decade. For most of that time, Chrome and Electron apps continued to use X11 by default, even when launched in a Wayland session. This wasn’t a big issue, since X11 apps work fairly well on Wayland by running inside an invisible X server called Xwayland. |
| 25 | + |
| 26 | + |
| 27 | + |
| 28 | +But running apps through an X11 compatibility layer is not the same as running them directly on Wayland. On Wayland, there’s less sitting between your app and the compositor, so there's lower overhead and much stronger isolation between applications. Modern Wayland compositors also let apps take advantage of newer platform and display features like variable refresh rates, fractional scaling, and HDR. |
| 29 | + |
| 30 | + |
| 31 | + |
| 32 | +These are good reasons for Electron apps to use Wayland whenever it’s available. In September, Electron 38 followed Chromium’s lead and began [defaulting to Wayland](https://www.electronjs.org/blog/electron-38-0#removed-electron_ozone_platform_hint-environment-variable). As apps began to update, people who had been “using Wayland” without issues for months or years started to find out what it was really like to experience their apps on Wayland for the first time. |
| 33 | + |
| 34 | +## Wayland’s house, Wayland’s rules |
| 35 | + |
| 36 | +Supporting Wayland required [dozens of changes](https://github.com/electron/electron/pulls?q=is%3Apr+wayland) throughout Electron, from Chromium internals to developer-facing APIs. It also required a different mindset. Wayland rethinks assumptions made by older systems about what desktop apps should be allowed to do, like: |
| 37 | + |
| 38 | +- Taking focus away from other apps |
| 39 | +- Viewing and interacting with windows from other apps |
| 40 | +- Responding to mouse and keyboard input when not focused |
| 41 | +- Choosing where to position their own windows on the screen (and which physical monitor to appear on) |
| 42 | +- Resizing windows at any time. |
| 43 | + |
| 44 | +Wayland’s answer to these questions is essentially “no.” When you launch an app on Wayland, the compositor (not the app developer) decides where it goes — typically centered on the active display. App windows don't resize or change focus without direct user input, and different apps can only interact with each other through optional [protocol extensions](https://wayland.app/protocols/) and [XDG portals](https://flatpak.github.io/xdg-desktop-portal/). |
| 45 | + |
| 46 | +In practice, apps on Wayland have a more restricted set of behaviors available to them compared to the same apps on X11 (including Xwayland). The exact behavior depends on the compositor. On KDE (KWin), for example, an app that tries to focus one of its windows will flash its icon in the panel instead. |
| 47 | + |
| 48 | + |
| 49 | + |
| 50 | +No one likes it when misbehaving apps steal focus or draw halfway off the screen. But for a cross-platform framework like Electron, Wayland's unique design philosophy makes platform parity more challenging. |
| 51 | + |
| 52 | +With that said, Wayland isn't only about taking away control from developers. In some areas, it gives them more power and flexibility than before. One example that difrectly impacts end users is client-side decorations. |
| 53 | + |
| 54 | +## Understanding CSD, or when a window isn’t a window |
| 55 | + |
| 56 | +The Wayland protocol is very lightweight, and its simplicy extends to an area as fundamental as window frames. On X11, the window manager typically supplies a window’s title bar and frame decorations. But when you create a window ([`xdg_toplevel`](https://wayland.app/protocols/xdg-shell))on Wayland, all you get back from the compositor is a plain rectangle. |
| 57 | + |
| 58 | + |
| 59 | + |
| 60 | +That rectangle is a powerful canvas. On a modern compositor like GNOME’s Mutter, it’s triple-buffered and GPU-accelerated. But if you want any of the trimmings that users might expect on their windows — title bar buttons, drop shadows, even resize handles — you have to add them all yourself. This requirement is called client-side decorations (CSD), and it’s one of the major differences between X11 and Wayland. |
| 61 | + |
| 62 | +Electron already had some support for client-side decorations, provided by a class called `ClientFrameViewLinux` which uses GTK to paint convincing native window frames entirely in-framework. This class was suddenly put to the test by many more developers and users when Electron flipped the switch in September. |
| 63 | + |
| 64 | + |
| 65 | + |
| 66 | +Electron's client-side window frames are "native" in the sense that they use GTK and derive style information from the platform, but they are not an exact match for the server-side decorations (SSD) users may remember from X11. With CSD, the details are implemented by each app or framework, so apps from different frameworks can look noticeably different side by side, right down to their drop shadows and corner shapes. |
| 67 | + |
| 68 | + |
| 69 | + |
| 70 | +The differences are usually minor, but when CSD is completely absent from a window, it can be pretty jarring. This was the case for one common window type in Electron apps. |
| 71 | + |
| 72 | +Prior to [Electron 41](https://www.electronjs.org/blog/electron-41-0), the frameless windows used by many popular Electron apps like VS Code, Obsidian, and Discord lacked CSD. That meant they had no shadows, external resize targets, or tiling borders on Wayland. Even if these apps didn’t want GTK-style title bars, they still required at least some CSD to not look like unfinished rectangles. on Wayland. |
| 73 | + |
| 74 | + |
| 75 | + |
| 76 | +Improving coverage for CSD was a task with framework-wide consequences. The biggest obstacle involved window sizes and how to measure them accurately. Electron already manages two different kinds of window boundaries: |
| 77 | + |
| 78 | +- **“window bounds”**, the size of the opaque window, including its titlebar, menubar, and frame. |
| 79 | +- **“content bounds”**, the size of the internal web view which hosts the app’s web content. |
| 80 | + |
| 81 | +Both values can be controlled independently by app developers. The framework converts between them internally, applying constraints and resolving any conflicts. |
| 82 | + |
| 83 | + |
| 84 | + |
| 85 | +But to have full coverage for CSD, Electron also needed to keep track of a new kind of boundary: |
| 86 | + |
| 87 | +- “widget bounds”, the size of the underlying transparent surface which draws everything inside of it, including the window frame, but also external decorations like drop shadows and resize targets. |
| 88 | + |
| 89 | +Effectively, CSD makes it so that the “real” window (represented internally as a Chromium “accelerated widget”) is larger than the opaque window which developers and users see and interact with. That part — the “logical” window — is inset inside the transparent widget. So a window that visibly measures 800x600 needs to be set inside a larger, transparent window that might measure something like 844x644 (depending on the GTK theme). |
| 90 | + |
| 91 | + |
| 92 | + |
| 93 | +All this complexity needs to be managed throughout the window lifecycle and across state changes. It also needs to be abstracted from other parts of the Electron API and app developers, who are generally not thinking about the extents of invisible resize targets as they query and manipulate widths and heights for their app. |
| 94 | + |
| 95 | +The good news: much of this was sorted out between last September and March, and as a result, Electron 41 supports CSD on Wayland in all window configurations, including frameless windows with [Window Controls Overlay](https://www.electronjs.org/docs/latest/tutorial/custom-title-bar). |
| 96 | + |
| 97 | +Now that the hardest part is behind us, CSD (and Wayland in general) opens up some interesting possibilities for Electron apps. Frameless windows can have nicely rounded corners. More platform features and user settings can be supported directly by the framework. And developers can have new ways to customize window frames and integrate them seamlessly with web content. The main limits are contributors and time. |
| 98 | + |
| 99 | + |
| 100 | + |
| 101 | +## What’s next |
| 102 | + |
| 103 | +Wayland is an everyday reality for Linux users in 2026, so from the perspective of the Electron project, supporting Wayland is now just a part of what it means to "support Linux." |
| 104 | + |
| 105 | +An important milestone was reached last month with the creation of a [Wayland test job in CI](https://github.com/electron/electron/pull/49908). Not every existing test has been ported over, but it’s now much easier to catch regressions. |
| 106 | + |
| 107 | +If you make an Electron app that targets Linux, and you haven’t thoroughly tested it on Linux in a while (even as recently as last fall), give it a spin with Electron 41+ on a modern Linux distribution like Ubuntu 25.10 or Fedora 43. You will likely discover changes you could make to accommodate the unique constraints inherent to Wayland. These are covered as best as possible in the [Electron documentation](https://www.electronjs.org/docs/latest/api/browser-window), but the best way to understand the new environment is to use it. |
| 108 | + |
| 109 | +And if you’d like to see faster progress and support for more Wayland features, come join us! Like Linux itself, Electron is a community-run [free software project](https://openjsf.org/blog/electron-joins-the-openjs-foundation) that’s [open to everyone](https://www.electronjs.org/community). |
| 110 | + |
| 111 | +Because Electron powers so many popular desktop apps, [contributing](https://www.electronjs.org/docs/latest/development/build-instructions-gn) is a great way to make desktop Linux even more viable for more people. There is so much going on right now across the Linux ecosystem, and we are actively looking for Linux contributors and maintainers to help keep Electron up to spec. |
0 commit comments