|
| 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 next-generation [Wayland](https://wayland.freedesktop.org/) display protocol last fall, most people likely didn't even notice. |
| 15 | + |
| 16 | +That's a good thing. Wayland is intended as the succesor to X11, and major Linux distributions have already been defaulting to it for years. Both KDE Plasma and GNOME 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 is late to the party. |
| 17 | + |
| 18 | +But a migration isn't complete without desktop apps, and the Linux app ecosystem went through a rapid Wayland transition after Chromium [turned on Wayland support by default](https://chromium-review.googlesource.com/c/chromium/src/+/6819616) in August. That move started a chain reaction which brought along Electron and dozens of Linux desktop apps which use it. |
| 19 | + |
| 20 | +## The third impact: Electron goes Wayland-native |
| 21 | + |
| 22 | +Wayland is supported out of the box in Electron 38.2 and newer. If your apps are up-to-date, you can go ahead and delete those config files filled with `VERY_LONG_OZONE_VARIABLE --with-extra-ozone=please`. It Just Works. |
| 23 | + |
| 24 | +The quiet switchover was only possible because 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, Wayland was disabled by default. This wasn’t a huge issue, since Chrome and Electron apps continued to work fairly seamlessly in Wayland sessions by running in an invisible X server (Xwayland). |
| 25 | + |
| 26 | + |
| 27 | + |
| 28 | +But there's a big difference between running apps in an X11 compatibility layer and running them directly on the new display server. 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. So 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) when launched in a Wayland session. And 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 -- for better and sometimes for worse. |
| 33 | + |
| 34 | +## Wayland’s house, Wayland’s rules |
| 35 | + |
| 36 | +Supporting Wayland required changes to every layer of the Electron framework, from the Chromium base, to the windowing system, to developer-facing APIs. It also required a new mindset for developers working on the Electron project and Electron apps. |
| 37 | + |
| 38 | +Wayland is much newer than not only the X Window System, but also the windowing systems used by Windows and macOS, all of which trace their roots to the ‘80s. The Wayland developers had the opportunity to revisit assumptions made by earlier systems, and ask questions like whether desktop apps should be able to: |
| 39 | + |
| 40 | +- Take focus away from other apps |
| 41 | +- View and interact with windows from other apps |
| 42 | +- Respond to mouse and keyboard input when not focused |
| 43 | +- Choose where to position their own windows on the screen (and which physical monitor to appear on) |
| 44 | +- Resize their windows at any time |
| 45 | + |
| 46 | +Wayland’s answer to these questions is “no” (or at least, “it depends.”) When you launch an app on Wayland, it appears centered on your active display, regardless of what the developer had in mind. It doesn't resize or change focus without direct user input. And it can only interact with other apps via optional [protocol extensions](https://wayland.app/protocols/) and [XDG portals](https://flatpak.github.io/xdg-desktop-portal/). |
| 47 | + |
| 48 | +The exact outcomes depend on the compositor: if your app tries to focus one of its windows on KDE (Kwin), for example, it will flash its icon in the panel instead. But generally speaking, apps on Wayland have a more restricted set of behaviors available to them compared to the same apps on X11 (including Xwayland). |
| 49 | + |
| 50 | + |
| 51 | + |
| 52 | +A lot of thought went into these decisions: no one likes it when misbehaving apps steal focus or draw halfway off the screen. But some apps are designed to expect a high level of programmatic control. Electron apps typically support multiple platforms and try to behave similarly on all of them, and the unique design philosophy of Wayland makes cross-platform parity a newly interesting challenge. |
| 53 | + |
| 54 | +But Wayland isn't all about taking away control. In some areas, developers have more power and flexibility than before. Let's zoom in one topic that directly impacts end users: client-side decorations. |
| 55 | + |
| 56 | +## Understanding CSD, or when a window isn’t a window |
| 57 | + |
| 58 | +The Wayland protocol is very lightweight compared to the X11 framework. Its focus on simplicity extends to areas 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 on Wayland (an [`xdg_toplevel`](https://wayland.app/protocols/xdg-shell#xdg_toplevel))‚ all you get back from the compositor is a plain rectangle. |
| 59 | + |
| 60 | + |
| 61 | + |
| 62 | +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. |
| 63 | + |
| 64 | +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. |
| 65 | + |
| 66 | + |
| 67 | + |
| 68 | +Client-side window frames drawn by Electron are “native” in the sense that they use the GTK toolkit and derive style information from the platform. But they are not an exact match for the “server-side” decorations (SSD) that previously came from window managers on X11. (Some Wayland compositors offer SSD via the optional [xdg-decoration](https://wayland.app/protocols/xdg-decoration-unstable-v1) extension, but it's more limited and not guaranteed to be available.) |
| 69 | + |
| 70 | +With CSD, every style choice and affordance has to be implemented by the app or framework. The result won’t always line up with user expectations, especially considering the sheer variety of customization options on Linux. These challenges aren’t unique to Electron by any means. If you put apps from different frameworks side-by-side on Wayland, you’ll notice they have different title bars and frame styles, and even different types of corner rounding and shadows. These outcomes are both a feature and a consequence of CSD and the flexibility it offers. |
| 71 | + |
| 72 | + |
| 73 | + |
| 74 | +The differences are usually minor. But when CSD is completely absent from a window, it can cause real usability issues. |
| 75 | + |
| 76 | +Prior to Electron 41, the frameless windows used by many popular Electron apps like VS Code, Obsidian, and Discord lacked any CSD. That meant they had no drop 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. |
| 77 | + |
| 78 | + |
| 79 | + |
| 80 | +Improving coverage for CSD in Electron 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: |
| 81 | + |
| 82 | +- **“window bounds”**, the size of the opaque window, including its titlebar, menubar, and frame. |
| 83 | +- **“content bounds”**, the size of the internal web view which hosts the app’s web content. |
| 84 | + |
| 85 | +Both of these values can be controlled independently by Electron app developers. The framework converts between them internally, applying constraints and resolving any conflicts. |
| 86 | + |
| 87 | + |
| 88 | + |
| 89 | +But to have full coverage for CSD, Electron also needed to keep track of a new kind of boundary: |
| 90 | + |
| 91 | +- “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. |
| 92 | + |
| 93 | +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). |
| 94 | + |
| 95 | + |
| 96 | + |
| 97 | +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. |
| 98 | + |
| 99 | +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). |
| 100 | + |
| 101 | +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 only limits are the imagination, and of course, contributors and testers. |
| 102 | + |
| 103 | + |
| 104 | + |
| 105 | +## What’s next |
| 106 | + |
| 107 | +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." |
| 108 | + |
| 109 | +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. |
| 110 | + |
| 111 | +But delivering a truly great experience for end users will take time and effort from both Electron contributors and Electron app developers. |
| 112 | + |
| 113 | +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. |
| 114 | + |
| 115 | +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). |
| 116 | + |
| 117 | +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