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 on a long road to a stack that still wouldn't be AI-first in any of the ways that now matter — building with AI, shipping AI features, or being readable by AI agents.

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 work with the entire codebase in context: every app, shared package, schema, doc, and rule in one place.

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, design tokens
  ui/           shared component library — deferred; the design system is tokens + written rules for now
  ai-orchestration/  AI feature layer — planned, scaffolding today
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)]

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. It was also the one part of the project that wasn't greenfield: working out the data models and edge cases of a legacy system, then moving them without breaking anything.

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 make the judgment calls. 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 What the AI got wrong

The guardrail system above started as deliberate design — I asked for best-practice rules up front, built around keeping the stack scalable and swappable. But it didn't stay static: some of its most specific rules exist because an agent made a specific mistake while I was still building the foundation. All three of these are from the first three weeks of commit history:

The pattern in all three: the code ran, and the flaw was architectural — the kind you only see by asking how the system will change later, not whether it works today. Each catch followed the same loop: fix it, write the rule, automate the check where a rule alone wasn't enough. That's why the guardrail counts below kept growing. These are the ones I caught early; I assume there are others, which is why verification is a standing gate and not a one-time audit.

06 By the numbers

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

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

07 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.