The challenge
The client's online learning platform was built on a legacy PHP/jQuery stack from 2016. Page loads averaged 3.8 seconds, the video player buffered constantly, and the admin panel was so slow that instructors dreaded uploading content. Course completion rates had flatlined at 35% — students were abandoning courses not because of content quality, but because the platform was painful to use.
They had 25,000 active students and 500+ courses. A rewrite needed to migrate all existing data, maintain Stripe subscription continuity, and redirect every existing URL to prevent SEO loss.
Our approach
We chose Next.js with tRPC for end-to-end type safety — from database schema (Prisma) through API layer (tRPC) to frontend (React). This eliminated an entire category of data-shape bugs that plagued the old PHP/REST approach.
Video streaming moved from self-hosted MP4 files to Mux with adaptive bitrate, reducing buffering by 95%. We designed a custom video player with resume-from-where-you-left-off, speed control, and chapter markers.
Key technical decisions:
- tRPC for type-safe API (no code generation, no schema files — just TypeScript)
- Mux for video hosting and adaptive bitrate streaming
- Chose NOT to do a gradual migration — the PHP codebase was too tightly coupled. Clean-room rebuild with parallel running.
- Prisma for type-safe database access with migration tooling
What we built
A modern learning platform serving 25k+ students with dramatically better UX:
- Course catalog with instant search, filtering, and SSR for SEO
- Custom video player with adaptive streaming, chapters, and progress tracking
- Student dashboard with learning streaks, progress analytics, and certificates
- Instructor CMS for course creation, analytics, and student management
- Stripe subscription management with plan upgrades, cancellations, and invoicing
- Full data migration: 25k users, 500+ courses, 150k+ enrollment records