Work

Kidjo 2025–Present

Three kids apps sharing one brand, one account and one subscription, migrated off a native Swift codebase into a single Flutter monorepo. The interesting part is not that they look alike. It is that they are one codebase.

kidjo.tv

Three apps, one codebase

Kidjo TV store listing frame: the app wordmark above a grid of cartoon video thumbnails, captioned enjoy more than 3000 videos
Kidjo TV app icon

Kidjo TV

3000+ videos

Live playback and offline downloads.

App Store
Kidjo Games store listing frame: the app wordmark above a row of game tiles, captioned great educational games and marked 3 to 10 years old
Kidjo Games app icon

Kidjo Games

40+ games

WebView games behind the same subscription.

App Store
Kidjo Stories store listing frame: the app wordmark above audiobook tiles, captioned 1000 amazing audiobooks for your kids
Kidjo Stories app icon

Kidjo Stories

1000+ audiobooks

Read along with a dyslexia-friendly reader.

App Store

10M+

downloads

3 platforms

Android, iOS and Web

Ages 2 to 10

COPPA-safe

The package graph

One Melos workspace on Dart pub workspaces. The apps are thin. What they share, a data layer and a design system, lives in packages they both depend on, and the dependency rules are enforced by the build rather than by agreement.

Package graph of the Kidjo workspace. Three app packages, kidjo_tv, kidjo_games and kidjo_stories, sit above two shared packages: core, an offline-first data layer behind LocalCache and ApiClient interfaces, and components, the shared design system. Every app depends on both shared packages. A crossed-out red link between two apps shows that no app may depend on another.

Content without a release

All three apps are data-driven players. The catalogue is not compiled in; it loads at runtime. New videos, new games and new audiobooks reach children without an app release, without a review queue, and without waiting for the slowest platform.

The shared data layer is offline-first, so a download keeps working on a plane or in a car, which for this audience is most of the time it gets used.

Kidjo TV store listing frame captioned watch videos offline, showing the video grid with an age filter set to three to five

Under the hood

Riverpod, hand-written

No code generation, so what you read is what runs.

go_router behind AppNavigator

Three apps route through one shared navigator.

get_it

Dependency injection across the workspace.

Swift origin

The native codebase these three apps replaced.

Full write-up: Flutter Monorepo Architecture with Melos