Engineering write-up

Rebuilding MRU's learning platform — solo, in five months, with AI

The platform code lives in a private org repo, so this is the architecture, the decisions, and the working method behind learn.mru.org — Marginal Revolution University's economics learning platform, rebuilt from Drupal 7 and shipped to production over five months in 2026 by one person (me), working with Claude Code and Codex.

TL;DR — Monorepo of web apps + a mobile client on a shared Supabase/Sanity backend — learn and marketing in production, the teacher app next — reaching 2.5 million learners a year and 20,000+ verified educators. Migrated off Drupal 7 with an idempotent pipeline and SEO-preserving redirects. AI wrote all of the code; the guardrail system is what made it safe to ship to production.

01 The situation

MRU had been on Drupal 7 for years — long past end-of-life. I was directing a slow, contractor-driven migration to WordPress when it became clear we were spending real money to arrive at a stack that still wouldn't be flexible, wouldn't be AI-ready, and would keep us dependent on outside developers for every change.

So I started building the alternative quietly. I fed our codebase and database into Codex and spent a month on the architecture, scaffolding, guardrails, and a working prototype. In March 2026 I brought the team the prototype and a roadmap.

Four months after the green light, it was in production — five months of build time in all.

02 The architecture

One repo, full product stack — chosen deliberately so AI agents always have read/write context of the entire system:

apps/
  web/          learner app (Next.js) — learn.mru.org
  teach/        teacher app (Next.js) — teach.mru.org, rebuild starting now
  marketing/    org site (Next.js) — mru.org, strangler-pattern proxy over legacy Drupal
  mobile/       learner app (Expo) — planned
packages/
  core/         shared logic: auth, learner progress, events, content gateways, search seams
  ui/           design system shared across apps
  ai-orchestration/  AI feature layer
docs/           canonical architecture & product truth (12+ documents)
agent-rules/    scoped AI guardrails (*.mdc)
flowchart LR
    subgraph Clients
        W[learn.mru.org
Next.js] X[Mobile
Expo — planned] T[teach.mru.org
Next.js — rebuild starting] M[mru.org
Next.js] end subgraph Backend[Shared backend] SB[(Supabase
identity · progress · events
RLS deny-by-default)] SA[(Sanity
content only, exit-proofed)] AL[(Algolia
derived, disposable index)] end W --> SB & SA & AL X -. planned .-> SB X -. planned .-> SA T -. planned .-> SB T -. planned .-> SA SA -. guarded reindex script .-> AL M -. strangler proxy
legacy pages .-> D7[(Legacy Drupal 7)]

Solid lines are live runtime connections; dotted lines are batch scripts, proxying, or planned wiring. The one-time Drupal → Sanity migration pipeline isn't drawn — it was a process, not an integration (see The migration below).

Strict responsibility boundaries, enforced in writing and in code review:

03 The migration

Migrating a decade of content off Drupal 7, solo, is mostly a risk-management problem:

Alongside the migration, I initiated and led the re-host of MRU's most-used product — interactive econ tools used by 600,000+ learners a year — from Heroku to AWS App Runner, with engineers on the team doing the hands-on work. It fixed the school-network blocking that had made the tools unreachable in classrooms.

04 How one person + AI ships production software

The honest answer: the AI writes all of the code, and I own every decision. The repo is built to be developed by agents, with the discipline living in version-controlled documents rather than in my head:

The result is a codebase where the AI has full context, hard rails, and a definition of done — and my job is the judgment: deciding what to build, setting constraints, verifying correctness, and owning the failure modes.

05 By the numbers

From the platform repo, as of August 9, 2026 (the repo is private under MRU's org — these are the stats I can share):

Commits274 (Feb 2026 → today, one committer)
TypeScript/TSX~42,000 lines across 308 files
Apps3 web (learn · teach · marketing) + 1 mobile (Expo)
Shared packagescore (auth, progress, events, content gateways, search seams) · ui · ai-orchestration
Test files40, plus Playwright browser suites and k6 load tests
Canonical docs13 architecture/ops documents
AI guardrail rules11 scoped .mdc rules + the AGENTS.md invariants
Time to production~5 months, solo

06 Scale and honesty

This is a nonprofit education platform, not a hyperscaler — but the reach is real: ~2.5 million learners on course and lesson pages in the past 12 months (GA active users, as of Aug 2026), 20,000+ verified educators, and spiky classroom-driven load on the interactive tools (600k+ active users in the past year). Because learning here is self-directed with no login wall, most learners never create an account — so traffic is heavily read-weighted with light writes, and anonymous experience quality matters as much as the signed-in one. The rebuild does add deliberate moments to create an account and save progress — building a richer signed-in relationship to support the platform's larger goal: identifying promising young learners and connecting them to MRU and Mercatus fellowship programs. Every architectural choice prioritizes low operational overhead and clarity over cleverness — it has to be runnable by a very small team, indefinitely.