01 ▍The SDUX Page
One tree, three renderers
A page is a typed tree — nav, header, main, footer — authored once on the server. Web renders it in Heex, iOS in SwiftUI, Android in Jetpack Compose. No web view and no shared UI code: each platform reads the same tree and answers in its own idiom.
02 ▍The design components
Atoms, molecules, organisms
Every node in that tree comes from one library. Atoms are the smallest named things — a heading, a link, an image. Molecules compose atoms into a unit; organisms own a screen's width. A component exists once all three platforms can render it, which is what stops one library quietly becoming three.
The component map →
03 ▍The OpenAPI spec
A single source of truth
The contract is not documentation written after the fact. One Elixir module generates it, and everything downstream is generated from that. A shape that isn't in the spec is a shape no platform can name.
Read the spec ⏺
04 ▍Typed HTTP clients
Apple's generator and Fabrikt
Swift OpenAPI Generator and Fabrikt turn that same spec into Swift and Kotlin models. Rename a field on the server and the clients stop compiling — a broken contract becomes a build error on a laptop instead of a crash in someone's hand.
05 ▍Scalability
Phoenix and Elixir on the BEAM
Every request renders in its own lightweight process. A page that fails takes itself down and nothing with it, latency stays flat as traffic climbs, and the same PubSub that serves these pages relays live audio to the phones.
06 ▍Deployment
Docker and mise
One task runner for a three-headed repo: regenerate the spec, regenerate the clients, run the suites, build the container, ship it. The commands a contributor types are the commands CI runs, which is why neither surprises the other.
07 ▍Declarative content
json.ex files
A page is a plain Elixir module that returns structs. No CMS and no template language — content is data, checked by the compiler, versioned in git, and reviewable as a diff. This page is one such file, and so is every page you have read here.
08 ▍Every endpoint
HTML and JSON
The same route serves a rendered page to a browser and the raw tree to an app. There is no second API drifting out of step with the site, because the site is the API. The apps are reading exactly this:
This page, as JSON ⏺