Native Cross-Platform Apps

In March, I had the chance to write about the Adwaita for Swift project on the official Swift blog. Adwaita for Swift is a declarative interface on top of the libadwaita and GTK frameworks, allowing the creation of fully native GNOME apps.

Some months earlier, The Browser Company published Swift bindings for WinUI 3, the native UI framework on Windows. Officially, Swift offers interoperability with C, C++, and Objective-C, but certain packages, such as JavaKit or PythonKit, add support for even more languages. Therefore, it is possible to use a huge range of UI frameworks in Swift code.

This is an ideal basis for a cross-platform UI framework.

Native Apps

Cross-platform UI frameworks like React Native primarily target mobile phones. While React Native offers support for Windows and macOS, the look does not fully match that of really native apps built using WinUI or SwiftUI. Native Linux UI frameworks like libadwaita and Qt are not supported at all.

While each platform has its own native look, there are obviously many parallels. As an example, there is a “flat navigation” pattern in each UI framework. Furthermore, it is very common to implement flat navigation with a sidebar or a view switcher.

My goal is to create a single UI framework around those patterns, allowing the creation of apps that look native on each supported platform.

Note

The following screenshots show a simple user interface built using the Aparoksha framework. Note that the framework is still in an early stage of development and currently supports only two platforms. I’ll mention later in this article why I want to share my project already.

A simple native GNOME app.
A simple native WinUI app.

Especially in an early state as now, but also when the framework is more mature, there are a lot of widgets in the native frameworks that are not implemented as a cross-platform widget (yet). Requesting new widgets is always possible via the forums or the Gitea issues, but certain widgets might not have an equivalent on other platforms. This fact has influenced the modular architecture of the project.

Architecture

The foundation of the project is the Meta package. It allows “converting” any imperative UI framework into a declarative framework. Find more information about my definition of a declarative design in the Meta documentation.

A declarative framework based on Meta is a backend. Currently, there are adwaita-swift and winui-swift, which are part of the Aparoksha framework, as well as the simple TermKitBackend. An up-to-date list is available on the Aparoksha website.

Note

Some of the repositories were previously developed on GitHub. The development will move to the Gitea instance of the Aparoksha project.

I’m leaving GitHub because of the points mentioned in this article.

Aparoksha is an umbrella backend, a backend that calls different other backends based on the detected platform or an optional environment variable.

As the backends are fully independent of the Aparoksha framework, they can provide platform-specific features that Aparoksha does not (yet) support. If one wants to create an app exclusively for one platform, one can directly import and use a backend.

In the same way, it is possible to define certain views specifically for one platform in apps built using the cross-platform Aparoksha framework.

Benefits for Adwaita for Swift

Having a separate package for the “translation” from imperative to declarative code led to numerous improvements for the Adwaita for Swift framework. Previously, it could happen that views were updated that did not actually have to be updated. This has been fixed. The current state of a widget’s property is always compared to the previous state before updating, if possible.

Furthermore, a much more simple and declarative syntax for creating widgets has been introduced. Note that the previous syntax may still be required for very complex or special widgets. The Adwaita for Swift documentation has been updated, find a short article here.

Models have been introduced for working with other APIs that require classes and should modify state.

Due to the modular design, it is easy to extend the Meta framework and add custom functionality. A simple example is the SQLite for Meta library.

As already mentioned, backends are fully independent of the Aparoksha framework. Using Adwaita for Swift directly will always be possible.

Why I’m Announcing the Framework So Early

The WinUI for Swift and the Aparoksha frameworks are still in early development. So, why am I announcing those projects already?

First, I want to encourage users of Adwaita for Swift to update their dependency. The repository is now available here, with the documentation being hosted here.

Second, I hope to spark the interest of some people with this article. I’ve decided to start the Aparoksha project with support for GNOME and Windows. I’d love to add support for other platforms as well:

If you have ideas for other platforms, I’m open to suggestions! Discuss them in the forums. Creating a declarative UI framework yourself is not too difficult. You can find a guide here, and I’m happy to answer questions in the forums!

It would be really cool if people who have the time and inclination to develop or contribute to a backend would take a look at the mentioned platforms. Finding contributors is the main reason I’m publishing this article.

If you want to use the Aparoksha framework, subscribe to the RSS feed here and wait some months for the introductory article.

Thanks in advance for any feedback and code! Don’t hesitate to share your ideas, concerns, and questions.

Comments

You can comment on this blog post by publicly replying to this post using a Mastodon or other ActivityPub/Fediverse account. Known non-private replies are displayed below.

Open Post