As soon as you have an open protocol you will have an ecosystem building up around it, and soon as you have an ecosystem you have people doing stuff differently. This is especially true when dealing with an open protocol built on a set of distributed pieces working together to create a whole.

atproto is such a protocol, system and ecosystem and it has a problem ... well it has many problems actually but I want to talk about one specific problem: How do we properly talk about this ecosystem and the varied ways people use different parts of it to create their vision? and especially how those decisions impact the goals of the protocol?

Segmenting the feature set: atidentity vs atproto.

If we're going to compare different apps and how and what parts of the protocol they use we first need to identify the parts the protocol consists of at a conceptual level.

(I'm going to assume a pre-existing familiarity with atproto so I won't go into detail on each of these. If you need it go find one of the many great introductions!)

Primarily I see atproto providing two things:

  • Identity and auth (atproto signing keys for DIDs)

    • DIDs are so close to having everything you need for an identity and auth layer. atproto defines the last little bit needed by using the verificationMethods field of DID documents to define a public key the corresponding private key of which (accessed through the PDS) can be used to authenticate API requests and sign data objects.

    • This provides the authentication backbone enabling the namesake "Authenticated Transfer"

    • I'll call it "atidentity" to separate it from the sync protocol

  • Data storage and sync (MST repositories and the firehose)

    • This is the main "value sell" of atproto and allows applications to sync user created data from user servers to application servers even across an untrusted network substrate.

    • The namesake "Authenticated Transfer" part of the protocol

The motherla- err motherapp?

Bluesky is the proof of concept app for atproto. If Bluesky is the PoC surely it will be using the protocol entirely and only as intended! r-right? Let's start our investigation here!

As the atproto native app it is Blueskys core is fully built on and uses the entire protocol. You exist on Bluesky as a DID with a signing key and a repo on a PDS. When you create a post your record will be created in your repository on your PDS and it will make it's way to the Bluesky servers via the sync protocol/"firehose".

However Bluesky also has a few features that don't do this. Chat is primary and oldest of the two but bookmarks also don't use this section of the protocol.

The introduction of chat to Bluesky caused the community to coin two terms to describe the difference between chat and the core Bluesky features: "On-protocol" and "Off-protocol". These are very useful terms! Essentially they refer to whether the data storage and sync layer is what actually gets used for the data layer. However the problem is we dont have anything more than these two right now and as such our discussions end up very binary: Either you're on-protocol or off of it. But many apps have off-protocol parts that are still meaningfully different in ways that are important to understand. This binary terminology limits our ability to communicate effectively.

Oh the repos we'll clone!

One of the most unique atproto applications around today is Tangled. Tangled is a git forge using atproto to build the social layer that fully fledged forges provide over a plain git host. Now you might have noticed an issue here: Git repos are not atproto repos, they're built of commits and not records and as such can't be (and even if they could probably shouldn't be) stored in PDSs and synced with the sync protocol. So what does Tangled do? A separate off-protocol git hosting service called a knot! Just like Bluesky chat and bookmarks this makes use of the fact that atproto allows you to use the authentication and identity layer on its own separate from the data storage and sync layer to provide a service that plays nicely with the atproto ecosystem.

This is where I'm going to draw the first line between what knots are and what Bluesky chat and bookmarks are: Knots may be "off-protocol" just like the others but are still more "atproto-native": They don't just provide git hosting you can log in to with an atproto account. They provide git, the platform, to atproto, the ecosystem. By that I mean that knots do things like define an XRPC API, use the sync protocol to get users SSH keys, git repos are defined by records in a users atproto repo. Knots don't just put git on top of atproto, they integrate the two systems together making something bigger out of their parts. This will especially be the case once the plans of knots broadcasting git events via the sync protocol come to fruition.

Another difference (an arguably more important one) is that of ethos. How "atproto-like" is a given secondary service. Bsky chat and bookmarks aren't very "atproto-like": Data is stored in a centralised server, the user doesn't have control over this data and even if they self hosted this central data store for themselves since it is centralised and there is no federation no one else will be able to chat with them. Knots however are quite "atproto-like" in the non-atproto features they provide. This happens to a great degree by virtue of git being decentralised. It's very easy to pull you git repo out and put it somewhere else. But knots are also designed with the ethos of user control and a distributed, federated substrate in mind: There is no one central knot. Tangled itself hosts a knot but you can host your own and everything works just the same as if you were on the one Tangled hosts. That's radically different from Bluesky chat.

Both "atproto-native" and "atproto-like" are somewhat nebulous terms and different people will undoubtedly have different opinions about to what degree a given service in the ecosystem is either, but nonetheless i think it can be a useful distinction to make in many cases. It's also worth noting that these two will often come hand-in-hand. As a service trends towards being "atproto-native" it will often also trend towards being "atproto-like" simply because being a more native citizen of the atproto ecosystem means being more "atproto-like".

You probably also know "atproto-like" from a variety of generic terms on the tech sphere like peer-to-peer, decentralised and federated. However you think these terms may or may not apply to and relate to atproto, the idea of "atproto-like" combines these ideas in the specific context of atproto.

If it quacks like a DB why not use it as one!

The last kind of application I want to quickly mention is things like atfile. Apps that I'm going to call "sync-less" applications. These are apps that use atproto for identity and data storage but don't use or need the sync capabilities of the protocol. In some ways this is very strange. The whole point of the "Authenticated Transfer protocol" is to enable the sync protocol. These apps use the PDS purely for its data hosting capabilities. Strange from a protocol perspective but can be quite useful in terms of UX (No need to make an account just to store your data somewhere you can always access!). They still end up providing many of the same benefits to users that the PDS storage model gives: Namely user control and ownership of their own data. I suspect this kind of app may become even more popular once private data arrives at PDSs.

Applications galore!

Now that we've established some new terminology let's put it into a wider context and use it to describe some more apps!

As Paul Frazee describes in this great bite sized leaflet, atproto fundamentally consists of app services and the user service (PDS).

App services are what we'll be judging using the framework layed out here. So time for an overview of apps, the primary services that make them up (ie. no relays or microservices or the like) and how they compare!

(i would use a table here but leaflet doesn't have support for those yet so bullet point list it is. hopefully i remember to come back to this later)

  • Streamplace

    • Indexer

      • On-protocol and thus about as atproto-native and atproto-like as you can get

      • Consumes the network firehose and builds up an index from it that it can then answer API requests based on.

    • Nodes

      • Off-protocol services for effectively distributing and syndicating streams

      • Quite atproto-native similar to knots: every node has its own DID and records and the sync protocol are used to organise syndication

      • Quite atproto-like: there is no single node with all the power instead nodes form a mesh network of sorts to share the burden of streaming among decentralised equals

  • Germ

    • Client

      • Not an app service in the traditional sense but it is here atproto is felt the most in Germ. Germ is a purely "atidentity" app and as such allows you to use your atproto identity with Germ

    • Transport service

      • Off-protocol service that provides the core transport layer between Germ clients allowing them to exchange messages

      • Very atproto-foreign. By design doesn't even know it exists.

      • Though quite atproto-like in concept: Will become a decentralised mesh of transport servers that users can chose between as they please

  • Leaflet

    • Client

      • Off-protocol local-first data storage

      • atproto-native in terms of atidentity

      • atproto-like in terms of local-first

    • Publications server

      • On-protocol (atproto-native and atproto-like) view of leaflets publicised to users atproto repos.

Conclusion.

I hope I've convinced you that there is much more detail in how apps deliver their features on atproto than "On-protocol" vs "Off-protocol" could ever hope to fully describe on it's own. And i hope my usage of "atidentity", "atproto-native" vs "atproto-foreign", "atproto-like" vs "atproto-unlike" and "sync-less" gives you some food for thought on how we talk about these things. Even if you, I and the ecosystem in general don't end up using these exact terms and categorisations I hope we start to talk more in detail about how apps are built on this protocol and what it means for how well they live up to the goals of the protocol.

I recommend you go read about all the varied apps on the protocol! Dig into how they work, read Tangleds blog, read the "How Streamplace works" blog/leaflets, read the Germ blog and most important of all be curious! and be critical! don't let anyone promise user control and not deliver on it!!

I also want to honorarily mention this excellent leaflet by the people behind Roomy. At the start of this post I separated atproto into the identity layer and the data layer. Currently both of these are provided by a users PDS but what the Roomy team advocate for here is essentially separating the two into separate services. Perhaps even spinning off the identity layer entirely as it's own thing (something ive thought about too). I'm not going to say I'm for or against these ideas but I think we should talk about them as a community.

As some last food for thought: The identity layer is separate and powerful enough that you could probably use it with ActivityPub as the data distribution layer instead of atproto sync. Maybe even add data signing onto ActivityPub (the lack of which me and others consider one of APs biggest weaknesses). How would be describe such a system? Is it atproto, ActivityPub, both or something fourth? Using the terminology I've described here you might call it an "atidentity ActivityPub app". Does that cover it well enough?