A curriculum that starts from what the reader already recites
Tadabbur is a Quranic Arabic learning app. The goal is narrow and stated plainly in its product document: help someone read an unfamiliar page of the Quran and understand its meaning and grammar, through daily practice that takes less time than a single prayer.
It ships as a Progressive Web App built in Flutter, on a Supabase backend — Postgres, Auth, Storage and Edge Functions, with 49 migrations and one edge function serving the review scheduler. The curriculum, the lesson player, an SM-2 spaced-repetition engine and on-device prayer-time calculation are live. The AI tutor and pronunciation scoring are not built.
Every general-purpose language app teaches the wrong thing first
The people who most want to understand the Quran already recite it. They have the sounds and none of the meaning. A conventional language curriculum starts from greetings and everyday nouns — vocabulary that will not appear in the text they actually read.
The constraint that made this hard: the curriculum had to be sequenced by frequency in the source text, not by pedagogical convention, and it had to be a content set one person could produce and quality-check alone.
Who it is for
Two readers, named before the first screen.
Sole designer and developer
Product document, curriculum sequencing, database schema, interface, Flutter architecture, tests, CI and deployment. 106 commits between 4 and 29 August 2026.
Write the product document first, then build against it
The product requirements document was written before any code: vision, two personas, success metrics with numeric targets, fourteen in-scope items and six explicitly out of scope. Nine further documents cover the schema, API design, Flutter architecture, information architecture, design system and testing strategy.
Key decisions and trade-offs
Supabase over Firebase, because the data is relational
The curriculum tree, the many-to-many mapping between words and verses, and the spaced-repetition query patterns are all deeply relational. Firestore would have forced denormalisation that fights that shape at every read.
Ships to the home screen, not to the app stores
Distribution is a website added to the home screen, with per-platform install instructions built into the app itself.
Free, with hard per-user AI cost caps instead of a paywall
The product document rules out monetisation entirely for v1. That is a cost decision as much as an ethical one: with no revenue to offset marginal AI spend, the control has to be usage caps rather than a payment wall.
In and out
Success metrics
Three checks, then the deploy
Every push to main runs flutter analyze, the full test suite, and a set of deployability checks before anything reaches the live site. CI and deploy are separate workflows, both with public status badges on the repository README.
Updates are never applied mid-session — a deploy cannot reload a user out of a lesson. It waits until they ask, or until the next launch.
Learn, Review and Prayer Times, live
- A Flutter PWA on Supabase — Postgres, Auth, Storage, Edge Functions — with 49 migrations and an edge function serving the review scheduler.
- Learn, Review and Prayer Times live. Prayer times are computed on the device with no network call.
- Roughly 4 MB cached on first run so the app works offline, with the rest of the rendering engine fetched in the background.
Build the thing the product is named after, first
Tadabbur is described as AI-first, and the AI tutor is one of four features sequenced in the plan and not yet built, with pronunciation scoring, gamification and push notifications. The core — curriculum, lesson player, review scheduler, prayer times — shipped in twenty-six days. The differentiator sat behind it in the plan and is still waiting. If I ran it again I would build the thing that makes the product different first, and let the conventional parts follow, because the conventional parts turned out to be the ones I could finish quickly.
This is how I make decisions at work too
Open to new roles — Toronto, hybrid, remote, or relocating.