SHARKPARTY
Case studies
Case study · Full-stack · Platform · Privacy

RORBT.

No gods // no hard centers // no masters

A privacy-first grassroots organizing platform—“organize without permission.” I designed and built it end to end: making organizing cheap, surveillance expensive, and co-option structurally impossible, one sovereign orbit at a time.

Role—Creator & sole engineer Live—rorbt.com
AstroTailwind v4TypeScriptCloudflare PagesWorkersDurable ObjectsD1R2Drizzlebetter-authWebSockets
// The thesis

The architecture is the politics.

Cheap to organize

Runs entirely on the Cloudflare edge—Pages, Workers, D1, R2. Hibernatable Durable Objects mean an idle orbit costs nothing, so the whole thing survives on donations, not a subscription.

Expensive to surveil

Member and newsletter data is encrypted at rest in R2. The real-time relay is key-blind and stateless. There is no central honeypot to subpoena.

Impossible to co-opt

Sovereign orbits, vouching-based trust, and a published protocol—no CEO, no hard center, no single point anyone can buy or capture.

Ships as a system

A monorepo with a shared design system (rorbt-glass), better-auth, Drizzle migrations, and oxlint/oxfmt—built to be maintained, not just launched.

// Architecture—Cloudflare-native, top to bottom

Real-time, at the edge, without a central honeypot.

Astro + rorbt-glass

A server-rendered Astro site and a shared component library / design system, deployed to Cloudflare Pages.

better-auth + D1

Identity, roster, and vouching on Cloudflare D1 (SQLite) through Drizzle ORM.

R2, encrypted

Member and newsletter lists stored encrypted in R2—decryptable only with keys the platform never holds in the clear.

OrbitRoom (Durable Object)

One hibernatable Durable Object per orbit holds the live WebSocket connections and fans messages out—key-blind, and it persists nothing.

The messaging relay is the sharp end of the design. Pages can't host a Durable Object, so OrbitRoom ships as its own Worker and binds back in. It's deliberately dumb: it gates nothing, holds no keys, sees no ciphertext, and persists nothing—it just fans already-authorized messages out to an orbit's live sockets, and hibernates the moment the room goes quiet. Privacy and cost fall out of the same decision.

// Field notes—the build, in writing

A decade of AWS intuition, re-earned on the edge.

Building RORBT meant relearning almost every mechanism I trusted—bindings instead of IAM, sagas instead of transactions, Durable Objects instead of locks and cron. This series is the field notes: real bugs, real error messages, real trade-offs I got wrong the first time. If you want the technical deep-end of this case study, it lives here.

10  Field notes~19k  Lines of TypeScript18  D1 migrations132  Tests
01 Cloudflare vs AWS: The Mental Model That Doesn't Transfer AWS-to-Cloudflare translation table, honestly graded: Lambda→Workers and S3→R2 mostly hold, D1 is not Aurora, and IAM's replacement—bindings as injected capabilities—is the one concept that doesn't map. Plus the cross-deployment Durable Object binding that actually bit me. Jun 4, 2026 02 Wrangler After Kubernetes Four sharp edges of wrangler.toml after years of Helm: compatibility_date as a base-image pin, Pages' undocumented two-environment limit, zero inheritance in [env.preview], and the .dev.vars precedence trap that silently pointed preview deploys at the production D1 database. Jun 10, 2026 03 Pages Functions vs a Cluster of Microservices Collapsing what would have been three or four services behind an ingress into a single Cloudflare Pages Functions directory—filesystem routing, middleware as code instead of sidecars, a D1-backed rate limiter, and the fallback bug where every unmatched /api/ route returns the SPA shell with a 200. Jun 13, 2026 04 Storage Without Transactions D1 gives you an atomic batch() that forbids data dependencies; R2 gives you etag compare-and-set and nothing else. How a guarded UPDATE shipped a silent permanent-data-loss bug, the executed_at column that fixed it, and a 17-write orbit-split saga journaled with a partial unique index instead of a distributed lock. Jun 19, 2026 05 Durable Objects Are the Actor Model Wearing a Database Costume Cloudflare Durable Objects give you mutual exclusion by construction—one single-threaded actor per orbit id—plus per-entity scheduling via setAlarm. What they don't give you is cross-store atomicity: the saga machinery stays, and serialization and transactions turn out to solve orthogonal problems. Jun 25, 2026 06 Testing Workers Against Real Bindings Getting @cloudflare/vitest-pool-workers running tests inside workerd against real D1 and R2: an ESM-only config trap, per-file (not per-test) storage isolation and the resetStorage that fixes it, seeding real better-auth sessions, and the rate limiter that fought back. Jul 1, 2026 07 better-auth After Auth0 Replacing Auth0 with the better-auth library on Cloudflare Pages: sessions as joinable rows, per-request plugin composition, three distinct 403s (trusted origins, missing Origin headers from React Native, and a pages.dev hostname we didn't own), and the silent Secure-cookie trap. Jul 6, 2026 08 Astro After Next.js Astro's islands versus the Next.js everything-is-React default, on a real Cloudflare Pages project: a 663 KB icon package that ships zero bytes to the browser, a hand-rolled catch-all route that silently ate a prerendered page, and the typechecking gap where nothing in the build verified my React components. Jul 14, 2026 09 Six Security Findings from One Day of Code Review One day of manual review on a Cloudflare governance platform: a CORS allowlist trusting an unclaimed pages.dev domain, hashed low-entropy tags posing as anonymization, a scalar trust score, GDPR erasure vs. an append-only hash chain, an HMAC unsubscribe token, and PII in logs. A scanner found none of them. Jul 22, 2026 10 Observability on the Edge Retrofitting structured, request-correlated logging onto Cloudflare Pages Functions: why winston won't run in workerd and pino loses its speed there, how AsyncLocalStorage carries request ids through 58 orphaned console.error calls without touching a signature, and a request-id scheme that survives system boundaries. Jul 27, 2026
Browse the series in the blog
// Outcome
Solo
Design → architecture → build
Edge-native
Cloudflare Pages + Workers
Idle = $0
Hibernatable orbits
Key-blind
Real-time relay

// Every layer—design system, auth, data model, real-time, content, deploy—is mine. This is the one where I got to make every call.

// Want the deep version?

Happy to talk through the hard parts.

Email Kam More work