← All Talks
Lightning Talk Development and Protocol

Using GraphQL to build with ATProto

Tim Ryan · @timryan.org
Sunday, March 29, 2026
4:20 PM – 4:30 PM PT
Performance Theatre
Available in-person & via livestream — Stream 2 (Performance Theatre)

When developing applications, there are a lot of client technologies that can talk to server backends. ATProto is extensible, federated, and works with backend data stores; GraphQL is often fixed for a specific application, precompiled, and yet performs a somewhat similar function. Because GraphQL tooling is common for application development (e.g. Relay, Apollo) it would make sense to bridge these two technologies so developers can bootstrap ATProto applications with widely available tools. My talk would explain my deep dive into this (starting with an Expo App) and some thoughts about how this would scale to introduce more developers into the ATmosphere.

On the top. Oh, yeah, there we go. From the top. GraphQL and app proto are what I sort of came to find out what they were comparing two different front end protocols for the social web. My background is I was a former social graph developer for eight years. I designed server to client APIs for web, cross platform APIs, working on native code, Android, and iOS. I worked on efficiency and latency challenges, building social media UIs and real-time data access to apps. And I found this tooling so good, and it was open source, and I used it in my own projects.

So naturally, the first time I came across atproto, I was like, wait, what is the difference between these two? I just described everything that may be true of atproto. So GraphQL is an ubiquitous library, and you don't have to take my word for it, you can just go to GraphQL.org and see the number of large companies that are using it, like Meta, AWS, GitHub. In my world, GraphQL was so ubiquitous that it was sort of like obvious that at least someone out there would be trying to make a comparison of the two technologies, given how you could just pop open a web browser, a web dev console and sort of see the uh the truth that like most websites are using it.

You know, one major social media website is not listed in that previous list, uh maybe because their CEO doesn't understand how GraphQL works. Let's not make that mistake today, let's find out. So, first, when I was looking at this problem, I was like, all right, well, I'll search uh uh GraphQL and atproto bridge is really someone will have documented this. And uh no, every single one of these results is someone not answering that question or a mismatch. Um the AI overview gives a description of what that would be, but that is not the answer. And unfortunately, uh now the top answer for this is this talk, which means this has to be the canonical answer to that.

Um so let's try to do a good job. Uh I join ask you to put on your GraphQL colored glasses as I, a GraphL developer tries to grapple with uh the Atmosphere. Um the source code for a demo if I have time, whatever, um, will be available at the bottom of this for the rest of the talk. Um quick intro to what GraphQL is if you're not familiar. So there's a website, GraphQL.org, there's an open source spec, and there's a foundation, which many companies have joined to work on it. Um it was built by Meta in 2012 to address uh resource constraints on their mobile applications, open source in 2015, and the foundation was launched in 2019.

Um you can see some things which are very similar to atproto, schema definition language, it wraps REST, much like XRPC, and there's types of schemas like Lexicon. Um maybe two differences. It controls how much data is fetched and ways to fetch data recursively, which I'll talk about. Um first is the GraphQL uh schema language. So here I've modeled a conference, an attendee and a location. Um you can see that it's very human readable. Um it was designed for front-end and back end collaboration. Uh it supports objects, interfaces, unions. Um, each field individually can accept uh arguments in return scalars or other types, and other fields can accept arguments as well.

I think this is the difference between atproto and GraphQL. Um like Lexicon, it's forward compatible. Uh, unlike Lexicon, you don't need to query all of the fields. So you know you could define a monolithic object like this, and you can only list the ID and the name, and you'll just get the ID and the name. Let's talk about querying. So here's an example of querying all the Star Wars films. We'll get the first three, um, and it will return a list of film objects, and all we're gonna do is pick up the title, not the ratings, not everyone's opinions about them, but just return what's on the right.

Um and GraphQL's query DSL has this like nice property where it kind of looks like the JSON on the right. So people really love that in live demos. Um then we could go and we could add another block here. Not only do I have the films, I want to add like, oh, I want to get the first three characters from each of the films and the response will update accordingly. One of the nice things about this um in GraphQL world is that like when you select an object and then you select subfields on it, you're doing this within the same request.

I think in H Proto you have you make it like a ref, and then you have to go resolve that ref with another network call. Um it's all resolved for you, and there's there's depending on how your back end is designed, this could be more efficient because you're basically doing a SQL join, not just two separate SQL calls. Okay, the atproto comparison, I'm gonna make an XRPC and I'm gonna get an object which eventually wraps uh a post, let's say. Um, this definition uh is sorry, I want to spend texting. Yeah, so this definition is interesting because the post is sort of like the canonical DB format, and there are patterns in uh Bluesky where you actually fork that and create a post view.

Um, this is the uh thing stripped of like it's like counts and follower count, uh like counts reply counts and everything, because it doesn't have that information when you publish it. So you need to create a lexicon view to sort of add that information in, and that's computed by the app view. So it sort of changes it from the GraphQL world where the consumer defines what data they're getting to you actually have to publish this and have a lexicon-oriented data model to show what you want. Let's look at the schema comparison. So this is an example of a post defined in GraphQL.

Looks very human readable. Here's an example of a post defined in Lexicon. It's certainly machine readable, but I wouldn't say it's human readable. Is there really a big difference between the two though? No, I think they're pretty homomorphic, even though the one on the right is much simpler and they don't have like constraints around strings, et cetera. And part of the reason for that is like, well, yeah, you could all run a bunch of annotations on the thing on the right. But really, we're just talking about data. And if data can be homomorphic, that means you can bridge the two, which will be the part of the talk I end on.

So I want to consider three scenarios or takeaways for HE devs. A is what GraphQL offers that is different from what exists in the Atmosphere. Now the second, oh yeah, and just as a top line summary is like um these are the sort of things that I talked about already. Um there's other things that I could get into, like generation via server definitions and like tooling, uh very robust ecosystem of tooling that's cropped up over the last decade and a half. I think a lot of these are just because of the age of the protocol, not things that won't actually come to the Atmosphere, but it's worth considering where developers are coming from when you're trying to give them a way to interface with um AT.

So question is GraphQL federated on the largest open source uh company's website, they actually list uh Apollo, they list that GraphQL has federation. Um but I will actually give you the example of what are first party APIs that you can consume GraphQL with. And I went to this page and I kept scrolling and I only came away with GitHub, GitLab, uh Shopify, and Yelp as examples. So really it's not federated if there are so few first-party implementations that they're willing to bank other people accessing. And I think the reason for that is the NSID. And the NSID means that I can actually publish something, let's take the Yelp review API.

I could publish an object from my API, which is the Yelp review API, if they were conforming to that schema. If they're conforming to GraphQL, you can't. I'm lying, it's not true. They could change it at any time, and that helps when you have a lossy lexicon inside of your own applications, but it doesn't accomplish federation. And what they mean for federation inside of um Apollo is actually federation across REST backends, GraphQL backends, et cetera. Try to take all the different data sources you might have and put them into one pipe, which is actually really attractive for an individual application.

So GraphQL's role in existing applications to bridge to app proto might be a lot of companies are using it. It consumes a lot of APIs. Maybe if we introduce atproto to those consumers, we can get more atproto connections and integrations into public apps. Um I'm gonna skip to uh my pitch about like what a new application could consider. Um eight minutes. Yeah. Uh so brief pitch for um, I started this by working on a Craigslist competitor marketplace style app, which I called Mothball. No relation to Anisota. Um, just this was the pitch I came in with.

I was gonna build an expo app and be like, what is it like to build an application with atproto integration? Um and I started with a GraphL uh mock GraphQL, and I was gonna move it to the server, and then I learned about atproto, and now I'm down this rabbit hole. So I was thinking low latency and mobile and web, there's some uh strategic benefit there with GraphL. You can do sensitive off-proto data, and you could wrap non-AT services, geocodings, search indexes, et cetera, behind a single API. Um that might be a case for using GraphQL as a front end for app proto on new apps.

But I think the best case scenario is actually this middle ground where we bridge the two. So now I'll stop there for questions, but while I show this demo really quick. I don't think we'll have to the demo is just this button. So here we go. This is uh the lexicon of uh XRPC request, and on the right I'm fetching live data from um the Atmosphere. Here's an example of doing multiple XRPCs in the same call from feed and from your actor. Um go check out my repo if you want to play around more with this code generation.

Thanks very much. Thank you, Tim. Awesome.