Overview
PhoniBear is a React Native / Expo app that teaches UK-curriculum phonics to Reception and Year 1 children — learn-a-sound lessons, decodable-word flashcards, tricky-words practice, and a trophy/progress system, alongside a parent dashboard for tracking progress and managing the subscription. It's a solo project, built end to end by me: product decisions, engineering, and the compliance work that comes with building something aimed at young children.
The problem
An app for children under a strict "safe for kids" bar has constraints that don't show up in a typical consumer app brief. No ads. A parent gate that a four-year-old can't accidentally bypass but a parent can use quickly. GDPR and children's-data compliance handled properly, not bolted on. And a curriculum-accurate phonics progression — this isn't generic edutainment, it follows the actual UK Grapheme-Phoneme Correspondence (GPC) sequence a Reception classroom would use, which meant the data model had to represent terms, GPCs, and word sets faithfully rather than just "levels."
What I built
The learning experience
Learn-a-sound lessons with phoneme audio playback, decodable-word flashcards, and a dedicated tricky-words mode for the common sight words that don't follow regular phonics rules (English has a lot of these, and a curriculum-literate app has to treat them differently to decodable words rather than lumping everything into one flashcard deck). A trophies and progress system gives children visible milestones without turning the app into a treadmill of streaks and notifications aimed at keeping a child engaged longer than is good for them.
Audio system
Phoneme audio playback via expo-av and expo-speech for text-to-speech, with caching so repeated sounds don't re-fetch or re-synthesize every time — important on a device with patchy connectivity, and for keeping the app responsive when a child taps the same sound repeatedly, which they will.
Parent gate and compliance
A parent gate that's deliberately awkward for a young child to pass but quick for an adult (React Native's affordances for that middle ground are limited — the usual trick of "hold for three seconds" or "solve a simple maths problem" both took some tuning to get right). Beyond the gate itself: a full GDPR and legal-compliance flow, an account-deletion path with a "deletion pending" banner and translated contact emails, and a market opt-in flow, all of which matter more for an app collecting data from and about children than they would for a typical consumer product.
Auth, payments, and infrastructure
Supabase handles auth. RevenueCat (react-native-purchases) handles the subscription paywall. react-intl/FormatJS covers i18n. Zod validates data shapes throughout, and AsyncStorage handles local persistence for offline-tolerant progress tracking.
Craft and housekeeping
A decent amount of the work here was the kind that doesn't show up in a feature list: componentising item rendering that had grown ad hoc, adding path aliases and shared utils, removing dead StyleSheet styles across six-plus screens, fixing a nested <Text> inside a <Button> that was silently breaking touch targets on some devices, and stabilising hook dependencies and animated refs that had accumulated lint-suppressed warnings.
Engineering decisions
Process discipline on a solo project
Even working alone, I set up Claude Code review and pre-commit hooks, ran a PR-based workflow with Copilot/Codex review integration, and kept Dependabot active. It's tempting to skip process on a solo side project — there's no team to enforce it — but the review and hook setup caught real issues (the nested-Text bug among them) that would otherwise have shipped.
Curriculum data as structured data, not hard-coded screens
Terms, GPCs, and word sets are modelled as a proper data pack (the current one is "UK English v1.1") rather than each lesson being its own hard-coded screen. That means extending the curriculum, or eventually supporting a different phonics scheme, is a data change rather than rewriting lesson components.
Stack
| Layer | Choice |
|---|---|
| Framework | React Native · Expo SDK 54 |
| Navigation | React Navigation (native stack) |
| Auth | Supabase |
| Payments | RevenueCat (react-native-purchases) |
| Audio | expo-av · expo-speech, with caching |
| Animation | react-native-reanimated |
| i18n | react-intl / FormatJS |
| Validation | Zod |
| Storage | AsyncStorage |
Reflections
The engineering here was less about any single hard problem and more about the accumulation of constraints a children's app carries that a typical consumer app doesn't: safety, compliance, curriculum accuracy, and interaction design that has to work for a four-year-old's motor skills and attention span at the same time as satisfying a parent checking in from the dashboard. None of those constraints are individually exotic, but building for all of them at once, solo, meant the process work — reviews, hooks, structured curriculum data — mattered as much as any single feature.