An Atmospheric Website

Tim Disney April 23, 2026
Source
I've migrated this blog four times over the past 20 years . WordPress, Jekyll, Hugo, Eleventy. Every few years I'd swap one set of tradeoffs for another and tell myself this was the last time. This is the fifth migration. It's also the last one. Not because I've finally found the perfect static site generator, but because the blog isn't really the thing anymore. My website is now a view over a repo I control on the open network, and the blog is just one of the things that view can show. In the atproto community, apps built on the protocol are called "Atmospheric." So: my website is now Atmospheric, and this post is about what that actually means. The migration treadmill Every blog platform I've used has been a compromise. WordPress gave me a CMS but tied me to a stack I didn't want to maintain. Jekyll, Hugo, and Eleventy gave me control and plain Markdown files, which I loved, but they quietly tied publishing to my laptop. To post something I needed to be at the right machine, in the right environment, with the right files, in the right git branch. If an idea hit me on my phone, it had to wait. And the data (posts, drafts, links I wanted to share, books I was reading) was scattered across a folder on my laptop, a Bluesky account, a reading app, a notes app. My "personal" website showed a sliver of me because most of my data lived somewhere else. I wanted a setup where the source of truth wasn't a folder on one machine, and where my website could pull from all the places I actually spend time online. Enter atproto Over the past few months I've been going deep on atproto, the protocol behind Bluesky and a growing ecosystem of other apps. I've already shipped a few things on it: Skyreader (an RSS reader), Skyboard (a kanban board), and SembleIt (an alternative client for Semble, a tool for collecting and sharing research links). What hooked me on atproto is how it inverts the usual relationship between apps and data. In a normal web app, your posts, bookmarks, notes, and tasks are rows in somebody else's database. On atproto, your data lives in your own repo, hosted on a server that by design can be moved. Apps write to your repo using shared schemas. Bluesky posts, Skyreader shares, Semble cards, and whatever comes next can all live in the same ecosystem, rendered by different clients . So what does "Atmospheric" mean for a website? It means my site is no longer a pile of Markdown files that get turned into HTML at build time. It's a SvelteKit app that reads directly from my atproto repo and renders that data into the public site. My blog posts now live in my repo as site.standard records, the same schema used by Leaflet, pckt, Offprint, and other long form writing apps. A record looks roughly like this: All 50 odd posts are fully imported, and new posts get published straight into the same system. Writing in the studio I needed somewhere to compose posts, so I built a small private admin I call the studio, accessible only to me through atproto OAuth. It's a handful of SvelteKit routes behind a sign in: a dashboard, a Markdown editor, a publish button. No database, no API server, no admin backend. Saving a draft writes a draft record straight to my repo. Publishing writes a site.standard.document record into the same repo the public site reads from. The whole authoring loop is OAuth tokens and XRPC calls. The neat side effect is that the studio isn't the only thing that can write to my repo. Any other app that speaks the site.standard.document lexicon could publish straight into it, and the post would show up on my site the same way. If someone builds a better editor tomorrow I can switch without migrating a single post. The CMS isn't welded to the website. The site as a view Here's the part that excites me: because the site is a renderer over my repo, it can surface anything I put in the repo. The new homepage reflects that. Alongside the blog, there are sections for things I've shared through Skyreader and research links from my Semble library. I don't maintain those sections by hand. I share an article in Skyreader or drop a card into a collection in Semble, and it shows up on the site automatically. The blog still lives at /blog, rendered from site.standard.document records. /reading surfaces links I've shared through Skyreader, and /library pulls cards and collections from Semble. I think of it as windows. Each app I use is a window onto some part of my repo. Skyreader is the window for sharing articles. Semble is the window for collecting research links. The studio is the window for drafting posts. The website is just another window, the public facing one, that pulls those pieces together for anyone visiting. Thinking this way changes what "adding a feature" to the site looks like. There's no schema migration, no data import, no scraping someone else's API. If I want a new section, I add a route, query the right lexicon from my repo, and render it. The data is already there because some other window put it there. The site catches up with my life rather than asking me to copy it in by hand. If I build or adopt a new Atmospheric app tomorrow, the website grows a new surface for it the day after. That's why this is the last migration. The site stopped being the thing I was building. It became a window onto a life that was already there.

Discussion in the ATmosphere

Loading comments...