Inkwell exists in three separate codebases now, which is either a sign of momentum or a sign I should learn to say no to myself. There's the iOS app, the thing the whole project actually started as. There's an experimental Android port, built from scratch rather than ported, because Compose and SwiftUI don't share code no matter how much you'd like them to. And there's a marketing website, which exists because apparently you need somewhere to point people that isn't a raw GitHub URL.

None of the three share a line of code. What they share is the actual point of the project: Standard.site records, AT Protocol identity, and the conviction that decentralised publishing deserves a proper native client rather than a web view wearing an app icon.

The Part That's Actually Done

The iOS app is the only one of the three I'm comfortable calling finished, or finished enough that I'd put it in front of a stranger. It reads and writes site.standard.publication and site.standard.document records straight off whichever PDS owns them, across a Read / Discover / Write structure that's stayed stable since pretty early on. It renders four different content formats — Markpub Markdown as the default, with native handling for Leaflet, pckt, and Offprint — and falls back to plain textContent when none of those apply, which matters more than it sounds like it should, because Standard.site standardises the metadata, not the body format, so something still has to handle whatever shows up.

Sign-in is OAuth against your own AT Protocol handle, no app password, with the session resumed silently from the Keychain afterwards so you're not relogging in every time you open the thing. Theming resolves the same way throughout: Leaflet's own light/dark palette first if a document has one, then standard.site's basicTheme, then whatever the system default is, overridable per document if a publication's general theme doesn't suit a specific piece. It's a small cascade, but it's the kind of detail that either exists or doesn't, and I'd rather it existed.

The Part That Isn't

Android is the honest opposite of all that. It's Kotlin and Jetpack Compose rather than Swift and SwiftUI, Hilt rather than @Environment, WorkManager rather than BGAppRefreshTask, OkHttp rather than URLSession — every architectural decision re-made on its own terms rather than copied across, because that's genuinely the only way to do it properly between two platforms with this little in common beyond the protocol underneath them. It mirrors the iOS structure deliberately — same three tabs, same theme-resolution cascade, same Constellation-based cross-repo comment discovery — but it's labelled experimental in its own README and I'm not going to pretend otherwise here. Feature parity is the goal. It isn't the current state.

The Bit Nobody Reads The Code Of

The website is the part I spent the least time defending to myself and the most time actually deciding on. The brief I gave it was restraint: no gradient hero, no animated counters, no pricing table that doesn't need to exist, none of the warm-cream-background, tiny-tracked-eyebrow-label aesthetic every SaaS landing page has converged on lately. Typography is meant to carry the page. If a section doesn't earn its place, it isn't there.

That's a deliberate choice for a site whose entire job is converting someone scrolling on their phone, mid-decision, into either a download or a GitHub visit. Editorial calm over sales floor, on the theory that a tool about owning your own writing should probably look like it believes that.

It's worth saying plainly: the GitHub link on that page is currently doing the work an App Store badge should be doing. That's not a design choice. That's ninety-nine dollars I haven't paid yet, which regular readers of this blog will recognise as a recurring character at this point.