Aardvark: Summer 2025 Update

It’s been a while, so here’s an update about Aardvark, our initiative to bring local-first collaboration to GNOME apps!

A quick recap of what happened since my last update:

  • Since December, we had three more Aardvark-focused events in Berlin
  • We discussed peer-to-peer threat models and put together designs addressing some of the concerns that came out of those discussions
  • We switched from using Automerge to Loro as a CRDT library in the app, mainly because of better documentation and native support for undo/redo
  • As part of a p2panda NLnet grant, Julian Sparber has been building the Aardvark prototype out into a more fully-fledged app
  • We submitted and got approved for a new Prototypefund grant to further build on this work, which started a few weeks ago!
  • With the initiative becoming more concrete we retired the “Aardvark” codename, and gave the app a real GNOME-style app name: “Reflection”

The Current State

As of this week, the Reflection (formerly Aardvark) app already works for simple Hedgedoc-style use cases. It’s definitely still alpha-quality, but we already use it internally for our team meetings. If you’re feeling adventurous you can clone the repo and run it from Builder, it should mostly work :)

Our current focus is on reliability for basic collaboration use cases, i.e. making sure we’re not losing people’s data, handling various networking edge cases smoothly, and so on. After that there are a few more missing UI features we want to add to make it comfortable to use as a Hedgedoc replacement (e.g. displaying other people’s cursors and undo/redo).

At the same time, the p2panda team (Andreas, Sam, and glyph) are working on new features in p2panda to enable functionality we want to integrate later on, particularly end-to-end encryption and an authentication/permission system.

Prototype Fund Roadmap

We have two primary goals for the Prototype Fund project: We want to build an app that’s polished enough to use as a daily driver for meeting notes in the near-term future, but with an explicit focus on full-stack testing of p2panda in a real-world native desktop app. This is because our second goal is kickstarting a larger ecosystem of local-first GNOME apps. To help with this, the idea is for Reflection to also serve as an example of a GTK app with local-first collaboration that others can copy code and UI patterns from. We’re not sure yet how much these two goals (peer-to-peer example vs. daily driver notes app) will be in conflict, but we hope it won’t be too bad in practice. If in doubt we’ll probably be biased towards the former, because we see this app primarily as a step towards a larger ecosystem of local-first apps.

To that end it’s very important to us to involve the wider community of GNOME app developers. We’re planning to write more regular blog posts about various aspects of our work, and of course we’re always available for questions if anyone wants to start playing with this in their own apps. We’re also planning to create GObject bindings so people can easily use p2panda from C, Python, Javascript, Vala, etc. rather than only from Rust.

Designs for various states of the connection popover

We aim to release a first basic version of the app to Flathub around August, and then we’ll spend the rest of the Prototype Fund period (until end of November) adding more advanced features, such as end-to-end encryption and permission management. Depending on how smoothly this goes, we’d also like to get into some fancier UI features (such as comments and suggested edits), but it’s hard to say at this point.

If we’re approved for Prototype Fund’s Second Stage (will be announced in October), we’ll get to spend a few more months doing mostly non-technical tasks for the project, such as writing more developer documentation, and organizing a GTK+Local-First conference next spring.

Meet us at GUADEC

Most of the Reflection team (Julian Sparber, Andreas Dzialocha, and myself) are going to be at GUADEC in July, and we’ll have a dedicated Local-First BoF (ideally on Monday July 28th, but not confirmed yet). This will be a great opportunity for discussions towards a potential system sync service, to give feedback on APIs if you’ve already tried playing with them, or to tell us what you’d need to make your app collaborative!

In the mean time, if you have questions or want to get involved, you can check out the code or find us on Matrix.

Happy Hacking!

Introducing Project Aardvark

Two weeks ago we got together in Berlin for another (Un)boiling The Ocean event (slight name change because Mastodon does not deal well with metaphors). This time it was laser-focused on local-first sync, i.e. software that can move seamlessly between real-time collaboration when there’s a network connection, and working offline when there is no connection.

The New p2panda

This event was the next step in our ongoing collaboration with the p2panda project. p2panda provides building blocks for local-first software and is spearheaded by Andreas Dzialocha and Sam Andreae. Since our initial discussions in late 2023 they made a number of structural changes to p2panda, making it more modular and easier to use for cases like ours, i.e. native GNOME apps.

Sam and Andreas introducing the new p2panda release.

This new version of p2panda shipped a few weeks ago, in the form of a dozen separate Rust crates, along with a new website and new documentation.

On Saturday night we had a little Xmas-themed release party for the new p2panda version, with food, Glühwein, and two talks from Eileen Wagner (on peer-to-peer UX patterns) and Sarah Grant (on radio communication).

The Hackfest

Earlier on Saturday and then all day Sunday we had a very focused and productive hackfest to finally put all the pieces together and build our long-planned prototype codenamed “Aardvark”, a local-first collaborative text editor using the p2panda stack.

Simplified diagram of the overall architecture, with the GTK frontend, Automerge for CRDTs, and p2panda for networking.

Our goal was to put together a simple Rust GTK starter project with a TextView, read/write the TextView’s content in and out of an Automerge CRDT, and sync it with other local peers via p2panda running in a separate thread. Long story short: we pulled it off! By the end of the hackfest we had basic collaborative editing working on the local network (modulo some bugs across the stack). It’s of course still a long road from there to an actual releasable app, but it was a great start.

The reason why we went with a text editor is not because it’s the easiest thing to do — freeform text is actually one of the more difficult types of CRDT. However, we felt that in order to get momentum around this project it needs to be something that we ourselves will actually use every day. Hence, the concrete use case we wanted to target was replacing Hedgedoc for taking notes at meetings (particularly useful when having meetings at offline, where there’s no internet).

The current state of Aardvark: Half of the UI isn’t hooked up to anything yet, and it only sort of works on the local network :)

While the Berlin gang was hacking on the text editor, we also had Ada, a remote participant, looking into what it would take to do collaborative sketching in Rnote. This work is still in the investigation stage, but we’re hopeful that it will get somewhere as a second experiment with this stack.

Thanks to everyone who attended the hackfest, in particular Andreas for doing most of the organizing, and Sam Andreae and Sebastian Wick, who came to Berlin specifically for the event! Thanks also to Weise7 for hosting us, and offline for hosting the release party.

The Long Game

Since it’s early days for all of this stuff, we feel that it’s currently best to experiment with this technology in the context of a specific vertically integrated app. This makes it easy to iterate across the entire stack while learning how best to fit together various pieces.

However, we’re hoping that eventually we’ll settle on a standard architecture that will work for many types of apps, at which point parts of this could be split out into a system service of some kind. We could then perhaps also have standard APIs for signaling servers (sometimes needed for peers to find each other) and “dumb pipe” sync/caching servers that only move around encrypted packets (needed in case none of the other peers are online). With this there could be many different interchangeable sync server providers, making app development fully independent of any specific provider.

Martin Kleppmann’s talk at Local-First Conf 2024 outlines his vision for an ecosystem of local-first apps which all use the same standard sync protocol and can thus share sync services, or sync peer-to-peer.

This is all still pretty far out, but we imagine a world where as an app developer the only thing you need to do to build real-time collaboration is to integrate a CRDT for your data, and use the standard system API for the sync service to find peers and send/receive data.

With this in place it should be (almost) as easy to build apps with seamless local-first collaboration as it is to build apps using only the local file system.

Next Steps

It’s still early days for Aardvark, but so far everyone’s very excited about it and development has been going strong since the hackfest. We’re hoping to keep this momentum going into next year, and build the app into a more full-fledged Hedgedoc replacement as part of p2panda’s NGI project by next summer.

That said, we see the main value of this project not in the app itself, but rather the possibility for our community to experiment with local-first patterns, in order to create capacity to do this in more apps across our ecosystem. As part of that effort we’re also interested in working with other app developers on integration in their apps, making bindings for other languages, and working on shared UI patterns for common local-first user flows such as adding peers, showing network status, etc.

If you’d like to get involved, e.g. by contributing to Aardvark, or trying local-first sync in your own app using this stack feel free to reach out on Matrix (aardvark:gnome.org), or the Aardvark repo on Github.

Happy hacking!