D-Bus is a disgrace to the Linux desktop
Source: Hacker News
What is D-Bus?
Everyone has heard about D-Bus, but what is it, actually?
D-Bus’ idea is pretty simple: let applications, services and other things expose methods or properties in a way that other apps can find them in one place, on the bus.
Imagine a service that monitors the weather. Instead of each app knowing how to talk to each weather service—or worse, implementing one itself—it can connect to the bus, discover any service exposing a weather API, and use it.
Great, right? And yeah, the idea is wonderful.
What went wrong?
D-Bus is a lenient, unorganized and forgiving bus. Those three traits lead to one of the biggest, fundamental, and conceptual blunders in any protocol, language or system.
The most important blunders are:
- Objects on the bus can register whatever they want.
- Objects on the bus can call whatever they want, however they want, whenever they want.
- The protocol allows—and even incentivises—vendor‑specific unchecked garbage.
In practice, this results in “Garbage in, garbage out.”
D-Bus standards, part 1
Apps need to communicate, right? Where do we find the way?
Uhh… somewhere online, probably. Nobody actually knows because the documentation is scattered, unfinished, unreadable, or convoluted. No client follows them consistently.
Let’s look at some “gems” (actual docs):

Truly secure.

I guess service implementors should learn telepathy.

So is it a draft or widely used?
D-Bus standards are a mess—assuming implementors on both sides actually follow them (they often don’t, as we’ll see).
D-Bus standards, part 2
Okay, let’s say we have a standard and we understand it. Great! Now…
Nobody gives a shit, literally. Even if you read a spec, nothing guides or enforces you to stick to it. You can send anonymous calls with whatever you want.
A personal story
When I was writing xdg-desktop-portal-hyprland, I had to use a few D‑Bus protocols (xdg portals run on D‑Bus). The portal documentation lists the protocols, so I implemented them. It worked more‑or‑less.
Then I added restore tokens, which allow an app to restore its previously saved share configuration. Here, D‑Bus falls apart.
None of the apps—fucking none—followed the spec. I wrote a spec‑compliant mechanism and nothing used it. Why? Because they all used a different spec that came out of nowhere; I couldn’t find a single doc about it. I ended up looking at KDE’s implementation and mimicking that.
Fun fact: THIS IS STILL THE CASE! The spec advertises a restore_token string property on SelectSources and Start, but no app uses it; they use restore_data in options instead.
D-Bus standards, part 3
One word: variants. Half of D‑Bus protocols use either this BS or an a{sv} (array of string + variant) passed somewhere.
Allowing such loosely‑typed data in a core spec should be banned. It lets apps send random junk over the wire and hope the other side understands it. This pattern has been tried many times (e.g., X atoms) and repeatedly leads to disaster.
D-Bus standards, part 4
Ever heard of permissions? Neither have D‑Bus developers. D‑Bus is as insecure as it gets: everyone sees everything and can call anything. If an app lacks a specific security mechanism, chaos ensues. Moreover, there is no universal concept of “rejection”; protocols either invent their own or just fail silently.
This is a prime reason Flatpak apps cannot see your session bus.
D-Bus standards, part 5
What about KWallet or GNOME Keyring? Supposedly “secret storage” for signing keys, passwords, etc., protected by a password.
In reality, once the store is unlocked, any app on the bus can read all secrets. No joke—after you enter the password, any app can silently read everything.
Enough is enough
I’ve had enough of D‑Bus in my apps. I would benefit from a session (and later, system) bus for my ecosystem, but I will not tolerate the absolute mess that D‑Bus is.
So I’m writing a new bus from the ground up, with zero copying, interop, or other recognition of D‑Bus. There are so many stupid ideas crammed into D‑Bus that I refuse to let them poison my own system.
XKCD 927
Many quote this XKCD comic for each new implementation, but the situation isn’t the same.
For example, with Wayland, when you switch you abandon X; you cannot run an X11 session together with a Wayland one. However, you can run two, three, or even 17 session buses. Nothing stops you. That’s why gradual migration is possible. Buses can’t talk to each other directly, but you can create a proxy client that translates D‑Bus APIs into new ones.
Wire
The first thing I focused on was hyprwire. I needed a wire protocol for Hypr* tools like hyprlauncher, hyprpaper, etc.
Hyprwire is inspired by Wayland’s approach. Its most important strengths are:
- Consistency – the wire enforces types and message arguments. No
a{sv}, no “just send something lol”. - Simplicity – the protocol is fast and simple. No complicated struct types that add annoyance.
- Speed – fast handshakes and protocol exchanges; connections are established quickly.
Hyprwire is already used for IPC in hyprpaper, hyprlauncher, and parts of hyprctl, and has been serving us well.
Bus
The bus is called hyprtavern. It isn’t exactly what D‑Bus is, but it’s more like a tavern.
Apps register objects on the bus, which expose protocols and key properties defined by those protocols. Other apps can discover these objects by connecting to the bus.
In a sense, hyprtavern acts like a tavern: each app is a client that can advertise the languages it speaks, and can strike up a conversation with another app if they share a language.
Overall improvements over D‑Bus (in no particular order)
- Permission handling (incomplete list)
(Further details omitted for brevity.)