Case study

ReadThat: A Reddit-Scale Client, Built for Real

4 min read

A Reddit-style Android/iOS/www client and Cloudflare backend, built to explore SDUI, offline-first architecture, media pipelines, and agentic development. Hub for the full case-study series.

ReadThat is my exploration of the system design, client architecture, and UI of Reddit. It essentially a limited function reddit clone backed by a Cloudflare Workers, D1, R2, and Streaming media. It’s my dive into the reddit engineering space. Some of the more interesting bits are a personalized server-driven feed, deeply nested comments trees, image/gallery/video posting, offline first architecture with optimistic UI, three-state voting, and an media feed with streaming video & photos.

Source: github.com/patjackson52/ReadThat

The Android SDUI feed, captured on device: ranked posts, image carousels, and inline video, all rendered from server-described cells.

Why build this

Reddit looks simple if you describe the screens: a ranked feed, a post detail, a tree of comments. It stops being simple when the product requirements become system requirements. This project exists to work those requirements for real, with several deliberate goals stacked on top of each other:

  • Explore the problem space honestly. Reddit has published an unusual amount of engineering detail on r/RedditEng: feed rewrites, comment-tree pre-computation, TTI instrumentation. ReadThat implements that public architecture rather than guessing at it. Nothing is decompiled or copied; it’s an independent implementation written from those posts.
  • Exercise agentic development. The repo was built with coding agents as first-class developers: enforceable architecture docs, deterministic seed fixtures, smoke scripts, and per-behavior JVM tests are what make an agent (or a human) able to verify its own work.
  • Practice Compose at depth. Not Column demos: LazyColumn key discipline, animateItem(), drawBehind thread rails, shared-element transitions, VerticalPager snapping, and frame-budget discipline.
  • Optimize media and networking on mobile. One process-wide HTTP/3 transport shared by API, images, and video; one ExoPlayer for the whole app; tiered preloading so video plays on frame 1; two-tier caches everywhere.
  • Push on Kotlin Multiplatform. The contracts that deserve sharing (:core:model, :core:observability) compile for Android, iOS, and browser JS. Jetpack libraries allow data layer through UI to be shared xplat.

The series

Each page stands alone; together they cover the full system.

  1. Client architecture: layered modules, MVVM + UDF, offline-first, two-tier caches, background workers, the Jetpack inventory, and which pieces are KMP.
  2. The SDUI feed: server-driven UI - what, why, & how.
  3. The media feed: Smooth efficient instant video and photos, no spinners.
  4. Post detail & comments: the deeply-nested-tree problem, data structures, two-phase loading, anti-flicker merging, metrics, and an A/B testing strategy.
  5. The data layer: Room schema, repositories, L1 memory + L2 disk for data, memory + disk for media, and how cache sizes get picked.
  6. Backend architecture: Cloudflare Workers, D1, R2, Images, Stream, Durable Objects, auth, ACLs, and HLS video that starts instantly.
  7. Observability: the metric contract, percentile SLOs, which metrics are levers for DAU and engagement, and what changes for international markets.
  8. International strategy: where the growth is, what’s different about serving it, and how a client platform team drives impact there.
  9. Networking deep dive: HTTP/3 connection migration across Wi-Fi/cellular, HLS through the CDN, cache identity, and respecting metered connections.
  10. Kotlin Flows in practice: how flows wire the layers together: observing UiState, observing Room, and multi-source combine.
  11. Kotlin Multiplatform: what can be shared vs. what should be, per layer, across Android, iOS, and the web, and why shared code multiplies AI agents.

Verified state

ClientKotlin, Jetpack Compose (Material 3), Paging 3 over Room, WorkManager
BackendTypeScript Cloudflare Worker + D1 + R2 + Images + Stream + Durable Objects
TestsAndroid feature suites, KMP suites (Android/iOS/JS), 24 Workers-runtime integration scenarios
On deviceRegistration, live SDUI feed, detail/comments, create/profile/settings verified on a physical Pixel 10 Pro
TransportAPI and images negotiated HTTP/3 on device; Stream fell back to HTTP/2 as expected

Everything in this series links to the actual code at main.