Building a WhiteWind to Leaflet Converter Out of Pure Spite

Sometimes the best motivation comes from frustration. And honestly? I was getting frustrated that nobody had built a proper tool to migrate blog content between AT Protocol publishing platforms.

Here's the thing: both WhiteWind and Leaflet are brilliant blogging platforms built on the AT Protocol . They're both doing interesting work in the decentralised publishing space. But if you wanted to move your content from one to the other? You were basically stuck manually copy-pasting and reformatting everything.

That seemed ridiculous to me. We're supposed to be building an open, interoperable web here. So I did what any reasonable developer does when faced with a problem that should be solved but isn't: I solved it myself.

What Actually Needed Converting

The challenge wasn't just moving text around. WhiteWind entries are stored as markdown with AT Protocol metadata, while Leaflet uses a structured block system for rich content. The converter had to:

Parse markdown into Leaflet's document blocks (headers, text, blockquotes, code blocks)

Handle rich text facets (bold, italic, inline code, links)

Convert WhiteWind blob URLs to proper at:// URIs

Transform the schema from com.whtwnd.blog.entry to pub.leaflet.document

Generate proper publication records with theme configuration

Plus it needed to work entirely in the browser with no backend, because who wants to trust some random server with their blog content?

The Technical Bits

The whole thing is built with vanilla HTML, CSS, and JavaScript. No frameworks, no build process, just files you can open and use.

Now, you might wonder why I didn't reach for my usual beloved tech stack—Svelte 5, SvelteKit, TypeScript, TailwindCSS—the works. That's normally my go-to for any web project. But honestly? I was that frustrated. I just wanted to sit down and bang out a working solution without any ceremony, dependencies, or build steps getting in the way. Sometimes spite-driven development means stripping everything down to the absolute basics and just making the damn thing work.

I'll probably refactor it to my normal tech stack at some point, but only when I can be bothered to.

The core conversion logic handles:

TID Generation: Using base32-sortable encoding to create proper AT Protocol record keysMarkdown Parsing: A custom parser that breaks content into Leaflet's block structureRich Text Facets: Proper byte-indexed facet parsing for formatting and linksAT-URI Conversion: Transforming WhiteWind's blob references into standard AT Protocol URIs

The markdown parser was probably the trickiest bit. Leaflet's block system is quite different from WhiteWind's straight markdown approach, so I had to handle state transitions between different block types while preserving formatting.

Why This Matters

Look, I get it. Most people aren't migrating between AT Protocol blogging platforms. Yet. But this kind of tooling is exactly what the decentralised web needs more of.

When platforms are truly interoperable, users aren't locked into any single service. Your content is yours, stored in your own AT Protocol repo , and you can move it wherever you want. But that only works if the tools exist to make migration painless.

So yeah, I built this out of spite. Spite that better interoperability tools didn't exist. Spite that people were stuck with manual migration. Spite that we're building a decentralised future but sometimes forgetting the practical bits that make it actually usable.

Try It Yourself

The converter is available on GitHub under GPL-3.0 - just download the files and open index.html in your browser.

To use it, you'll need your WhiteWind entries JSON (grab it from your PDS at /xrpc/com.atproto.repo.listRecords?repo=[your-did]&collection=com.whtwnd.blog.entry), your DID, and a few minutes to configure your Leaflet publication settings.

It's not perfect - experimental software rarely is - but it works. And sometimes "works" is all you need to scratch that particular itch.

If you spot bugs, have ideas for improvements, or just want to help refine it, I'd love the help. Pull requests welcome.

And before anyone asks - yes, I'll likely stick with WhiteWind for my own blog. I'm just... not wanting to refactor a core aspect of my website and template for a different blogging platform. At least not right now. Sometimes you build tools for other people's problems, not your own.

The beautiful thing about building on open protocols is that tools like this can exist. Your content isn't trapped in some proprietary format. It's just data, following open standards, ready to be moved wherever you want it.

That's the future I want to help build. One conversion tool at a time.