On Hackernews, many have been arguing against desktop apps written with heavy bases such as Electron, or just web apps for that matter.

On mobile, most users still prefer native apps as well.

So, why are people using Electron and others?

1. Context

In 2011, I decided to try to write a simple python application using GTK2, and quickly ported it to GTK3. It wasn’t particularly nice to use, nor was it well documented.

In 2023, I decided to port it to GTK4, having worked on many web apps in the meantime.

The experience has changed a little bit, but not very much.

Note
I have used the GTK api directly, and I did not use a builder such as Glade/Gnome Builder, mainly because they don’t work well for Python or at all (Gnome Builder).

2. Things that got better from GTK3 to GTK4

2.1. Uniformity

The API seems a bit more uniform, such as a common way to add items inside a container with .append() instead of a mix of .addChild(), .add().

This goes hand-in-hand with many things just being Gtk.Box instead of their own special containers.

2.2. API documentation

The API documentation now clearly references since which version a method/feature is present or deprecated.

Searching for a method works much better too.

2.3. Libadwaita

The decoupling of GTK4 and Adwaita makes it feel more like a UI framework you’d find in the javascript world, albeit partially.

It seems to makes some things simpler, but I’ve seen little of that in my specific usecase so far.

3. Things that did not improve from GTK3 to GTK4

3.1. Tutorials and documentation

I’ve noted the improvements of the API documentation, but you’ll also note that it’s a C API.

You want to know the Python API? Good luck with that.

You can get a simple tutorial to get started, but the API docs are not up to date with GTK4, and do not cover Adwaita at all.

Some users have put together a github repository with a working list of examples because of this issue.

So, you basically have to grok the C API, and try to guess how this translates into Python.

Even though deprecations are clearly marked in the API docs, they always lack any example, and they also don’t really tell you what to use instead of a deprecated component.

For example, GTK.TreeView is marked as deprecated, which is great. But it does not tell you what to use instead. You’re left searching online for what to use instead, and you find that information on a release note only.

ChatGPT is not very good at GTK4 either, by the way.

3.2. Lack of auto-completion and documentation in the bindings

GTK is first and foremost a C library, so Python bindings are generated somehow.

But it’s a big pain, because auto-completion in your IDE does not work, and the methods don’t even come with the documentation attached.

So imagine you create a new box:

box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
box.`press tab on your keyboard`

And you get nothing at all.

You can’t go to the definition of Gtk.Box, and you cannot know the list of methods that you can use on that object.

You have to go to the online api doc, see what’s possible, maybe opening other pages for the parent class methods, understand how you’re supposed to use it, convert it in your head into what you think the generated methods are named, and run it to see if it works.

Wanna use a dropdown as recommended?

Just search github directly for examples, and hope that someone already figured that out so that you get a better feel on how to use it.

3.3. Lack of migration tools

From GTK3 to GTK4, many events are specified differently. I mostly got to know while trying to run the app and see it fail with a message telling me that event is now unknown.

No tools are provided to help developers migrate all of those for you, especially in Python.

4. Conclusion

The GTK and Gnome community has pushed GTK into the right direction overall, with better polish to the API, nicer components, and starting to fix long standing bugs.

But GTK stays a C API first and foremost, and using it in Python is a pain with a development experience from the 1990s at best.

So, why would I trade great documentation and debugging in HTML/CSS/Javascript, with lots of example, easy multiplatform and great mobile/desktop compatibility and accessibility? It’s also faster to implement, and so cheaper.

I would not recommend starting a new Python app with GTK in 2023, nor did I in 2011.

Yet, things could be a lot better:

  • Add multiple working examples into the API doc for each and every component;

  • If you deprecate something, tell developers what to use directly in the API doc;

  • Always attach method signatures and documentation into the generated language bindings in Python;

  • Each example should be working for each officially supported language (C, Python, Vala, etc.);

  • Help applications with migration scripts for each release for each supported language.

Looking at other language bindings, it seems like the Rust bindings seem to provide more examples, and better documentation overall. That might be a better choice.