+++
title = "Native Cross-Platform Apps"
description = "Develop beautiful apps following the design guidelines of the GNOME desktop."
date = 2024-10-17
[taxonomies]
tags = ["Aparoksha", "GNOME", "Swift"]
[extra.comments]
host = "mastodon.de"
user = "david_swift"
id = "113323819984442266"
+++

In March, I had the chance to write about the _Adwaita for Swift_ project <a class="external" href="https://www.swift.org/blog/adwaita-swift/">on the official Swift blog</a>.
_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 <a class="external" href="https://substack.com/home/post/p-138384240">published Swift bindings for WinUI 3</a>, the native UI framework on Windows.
Officially, Swift offers interoperability with C, C++, and Objective-C, but certain packages, such as <a class="external" href="https://github.com/swiftlang/swift-java">JavaKit</a> or <a class="external" href="https://github.com/pvieito/PythonKit">PythonKit</a>, 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.

{% alert(tip=true) %}
**Short summary:**
I'm creating a cross-platform UI framework
for Swift, based on the native UI frameworks for each of the supported platforms.
This is still very experimental.
{% end %}
<br>
<a class="inline-button" href="https://aparoksha.dev/">Check out the project's homepage</a>

## 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.

{% alert(note=true) %}
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.
{% end %}

<div class="row">
    <div class="column">
        {{ image(url="GNOME.png", alt="A simple native GNOME app." transparent=true) }}
    </div>
    <div class="column">
        {{ image(url="Windows.png", alt="A simple native WinUI app." transparent=true) }}
    </div>
</div>

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 <a class="external" href="https://forums.aparoksha.dev/t/ideas">forums</a> or the <a class="external" href="https://git.aparoksha.dev/aparoksha/aparoksha/issues">Gitea issues</a>, 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 <a class="external" href="https://git.aparoksha.dev/aparoksha/meta">Meta package</a>.
It allows “converting” any imperative UI framework into a declarative framework.
Find more information about my definition of a declarative design in the <a class="external" href="https://meta.aparoksha.dev/documentation/meta/declarativedesign">Meta documentation</a>.

A declarative framework based on Meta is a backend. Currently, there are <a class="external" href="https://git.aparoksha.dev/aparoksha/adwaita-swift">adwaita-swift</a> and <a class="external" href="https://git.aparoksha.dev/aparoksha/winui-swift">winui-swift</a>, which are part of the Aparoksha framework, as well as the simple <a class="external" href="https://git.aparoksha.dev/david-swift/term-kit-backend">TermKitBackend</a>.
An up-to-date list is available <a class="external" href="https://www.aparoksha.dev/backends/">on the Aparoksha website</a>.

{% alert(note=true) %}
Some of the repositories were previously developed on GitHub.
The development will move to the <a class="external" href="https://git.aparoksha.dev/">Gitea instance</a> of the Aparoksha project.

I'm leaving GitHub because of the points mentioned <a class="external" href="https://sfconservancy.org/GiveUpGitHub/">in this article</a>.
{% end %}

<a class="external" href="https://git.aparoksha.dev/aparoksha/aparoksha">Aparoksha</a> 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 <a class="external" href="https://adwaita-swift.aparoksha.dev/documentation/adwaita/creatingwidgets">here</a>.

<a class="external" href="https://meta.aparoksha.dev/documentation/meta/model">Models</a> 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 <a class="external" href="https://git.aparoksha.dev/aparoksha/meta-sqlite">SQLite for Meta</a> 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 <a class="external" href="https://git.aparoksha.dev/aparoksha/adwaita-swift">here</a>, with the documentation being hosted <a class="external" href="https://adwaita-swift.aparoksha.dev/documentation/adwaita/">here</a>.

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:

- KDE
- macOS
- iOS
- Android

If you have ideas for other platforms, I'm open to suggestions! Discuss them in the <a class="external" href="https://forums.aparoksha.dev/">forums</a>.
Creating a declarative UI framework yourself is not too difficult. You can find a guide <a class="external" href="https://meta.aparoksha.dev/documentation/meta/createbackend">here</a>, 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](/rss.xml) and wait some months for the introductory article.
Follow <a class="external" href="https://mastodon.de/@aparoksha">Aparoksha on the Fediverse</a> for more frequent updates on the latest changes.

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