Narrly — AI bedtime stories where your child is the hero and you choose the lesson. 20 values, 8 languages, native Kazakh narration, parent voice cloning.
TypeScript
0
2 commits
updated Jul 9, 2026
Narrly writes an original illustrated fairy tale around your child, in their language, and reads it aloud — in a character's voice, or in your own.
Children learn values from stories, not from lectures. A child forgets being told to be brave, but remembers the hero who was. Reading together at bedtime is also the one screen-free ritual that reliably brings a parent and a child closer, and it builds the reading habit at the age when it still forms easily.
But finding the right story is hard. A book on the shelf rarely teaches the value your child needs this week, it never features your child, and a parent at the end of a long day has no energy left to invent one.
A parent picks their child's name, the value they want the story to teach, and — if they like — the people the child loves, who join the tale as characters. Narrly writes an original three-panel adventure where the child is the hero, illustrates it, and narrates it aloud. Under a minute, in any of eight languages.
The narration can be read by a story character, or in the parent's own cloned voice — so a child whose mother or father works away can still fall asleep to their voice.
![]() The child is the hero — and the people they love join the cast | ![]() Twenty values. Exactly one per story. |
![]() Ten seconds of your voice, and it narrates every story | ![]() A free library of world folk tales, Kazakh ones included |
The same app on a phone — read the story, then talk about it together.
A React Native client talks only to Supabase Edge Functions. Every model provider key lives server-side; the app never sees one. Each AI capability is a chain — if a provider is down, throttled, or out of credit, the next one takes over transparently.
flowchart TD
A["React Native · Expo<br/>iOS · Android · Web"] -->|"HTTPS + Supabase Auth"| B["Supabase Edge Functions<br/>(Deno)"]
B --> C["generate-story"]
B --> D["generate-illustrations"]
B --> E["generate-audio"]
B --> F["clone-voice"]
B --> G["dodo-webhook"]
C --> C1["DeepSeek V4 Flash<br/>→ Claude 4.5 Sonnet<br/>→ Groq → Gemini"]
D --> D1["FLUX via fal.ai<br/>text-to-image, then image-to-image<br/>to keep the same child in every panel"]
E --> E1["Kazakh: FreedomSpeech (native)<br/>→ self-hosted MMS-TTS-kaz<br/>Other languages: Higgs TTS 3"]
F --> F1["ElevenLabs<br/>instant voice cloning"]
B --> H[("Postgres<br/>Auth · Storage · RLS")]
Things worth a look if you are reading the code:
supabase/functions/_shared/guard.ts — one guard for every function: auth, rate limiting, monthly story quota, upstream timeouts, and generic errors so a provider failure never leaks its identity to the client.supabase/functions/generate-story/index.ts — the child's name travels to the model as data, never as instructions, so a name like ignore previous instructions is written into the story rather than obeyed. Names are also profanity-checked before they can reach a prompt.supabase/functions/generate-illustrations/index.ts — the first panel's illustration becomes the reference image for the next two, which is what keeps the same child on every page.supabase/functions/generate-audio/index.ts — long stories are chunked, synthesised in parallel and merged back into a single WAV, then cached so a re-listen costs nothing.| Layer | What we use |
|---|---|
| App | React Native 0.81 · Expo SDK 54 · expo-router · Reanimated |
| Web | The same React Native codebase, plus a static marketing site in vanilla HTML/CSS |
| Backend | Supabase Edge Functions (Deno · TypeScript) |
| Data | Postgres with Row Level Security · Supabase Auth · Storage |
| Story text | DeepSeek → Claude (via Replicate) → Groq → Gemini |
| Illustration | FLUX via fal.ai |
| Narration | FreedomSpeech (Kazakh) · Higgs TTS 3 · ElevenLabs |
| Payments | Dodo Payments (Merchant of Record) |
| Hosting | Vercel (marketing site + web app) |
mobile/ React Native + Expo app — iOS, Android and web from one codebase
landing/ Static marketing site (narrly.org), hand-written HTML/CSS, 8 languages
supabase/ Edge Functions (Deno) and SQL migrations
infra/ Self-hosted Kazakh TTS endpoint
ios-launch/ App Store assets
You will need your own API keys — none are included here, and none ever were (see below).
# 1. The app
cd mobile
npm install
cp .env.example .env.local # fill in your Supabase URL + anon key
npx expo start # press w for web, or scan the QR code
# 2. The marketing site — no build step, it is plain HTML
cd landing
python -m http.server 8000
# 3. The backend
npx supabase functions deploy generate-story
npx supabase secrets set DEEPSEEK_API_KEY=... FAL_KEY=... FREEDOMSPEECH_API_KEY=...
Only EXPO_PUBLIC_* values are read by the client. Model provider keys live exclusively
in Supabase Edge Function secrets and are never bundled into the app.
This is a public mirror of a live commercial product, published so the work can be read and reviewed. A few things are held back on purpose, and the code says so where they are:
No API key has ever been committed to this project. Secrets live in Supabase Edge Function
secrets and in a local .env.local that git has never tracked.
Live and in early access. The web app runs at app.narrly.org; Android builds ship through EAS, and iOS is in preparation.
© 2026 Narrly. All rights reserved.
The source is published for reading and review. It is not open source: you may not use, copy, modify or distribute it, in whole or in part, without written permission. See LICENSE.
Многие дети растут без простых человеческих ценностей — их воспитывает экран, а не близкий человек. Сказки же всегда были самым естественным способом что-то привить: ребёнок забудет нотацию, но запомнит героя. А чтение вместе перед сном сближает родителя и ребёнка и формирует привычку к чтению с ранних лет.
Narrly создаёт персональную иллюстрированную сказку, где главный герой — сам ребёнок, и учит одной выбранной ценности: доброте, честности, смелости. Сказку можно послушать — её озвучат голоса персонажей или голос близкого человека, чтобы даже когда мама или папа далеко, ребёнок засыпал под их голос.
Восемь языков, включая казахский с нативной озвучкой.
Сделано в Казахстане 🇰🇿
Narrly — AI bedtime stories where your child is the hero and you choose the lesson. 20 values, 8 languages, native Kazakh narration, parent voice cloning.
TypeScript
0
2 commits
updated Jul 9, 2026
Narrly writes an original illustrated fairy tale around your child, in their language, and reads it aloud — in a character's voice, or in your own.
Children learn values from stories, not from lectures. A child forgets being told to be brave, but remembers the hero who was. Reading together at bedtime is also the one screen-free ritual that reliably brings a parent and a child closer, and it builds the reading habit at the age when it still forms easily.
But finding the right story is hard. A book on the shelf rarely teaches the value your child needs this week, it never features your child, and a parent at the end of a long day has no energy left to invent one.
A parent picks their child's name, the value they want the story to teach, and — if they like — the people the child loves, who join the tale as characters. Narrly writes an original three-panel adventure where the child is the hero, illustrates it, and narrates it aloud. Under a minute, in any of eight languages.
The narration can be read by a story character, or in the parent's own cloned voice — so a child whose mother or father works away can still fall asleep to their voice.
![]() The child is the hero — and the people they love join the cast | ![]() Twenty values. Exactly one per story. |
![]() Ten seconds of your voice, and it narrates every story | ![]() A free library of world folk tales, Kazakh ones included |
The same app on a phone — read the story, then talk about it together.
A React Native client talks only to Supabase Edge Functions. Every model provider key lives server-side; the app never sees one. Each AI capability is a chain — if a provider is down, throttled, or out of credit, the next one takes over transparently.
flowchart TD
A["React Native · Expo<br/>iOS · Android · Web"] -->|"HTTPS + Supabase Auth"| B["Supabase Edge Functions<br/>(Deno)"]
B --> C["generate-story"]
B --> D["generate-illustrations"]
B --> E["generate-audio"]
B --> F["clone-voice"]
B --> G["dodo-webhook"]
C --> C1["DeepSeek V4 Flash<br/>→ Claude 4.5 Sonnet<br/>→ Groq → Gemini"]
D --> D1["FLUX via fal.ai<br/>text-to-image, then image-to-image<br/>to keep the same child in every panel"]
E --> E1["Kazakh: FreedomSpeech (native)<br/>→ self-hosted MMS-TTS-kaz<br/>Other languages: Higgs TTS 3"]
F --> F1["ElevenLabs<br/>instant voice cloning"]
B --> H[("Postgres<br/>Auth · Storage · RLS")]
Things worth a look if you are reading the code:
supabase/functions/_shared/guard.ts — one guard for every function: auth, rate limiting, monthly story quota, upstream timeouts, and generic errors so a provider failure never leaks its identity to the client.supabase/functions/generate-story/index.ts — the child's name travels to the model as data, never as instructions, so a name like ignore previous instructions is written into the story rather than obeyed. Names are also profanity-checked before they can reach a prompt.supabase/functions/generate-illustrations/index.ts — the first panel's illustration becomes the reference image for the next two, which is what keeps the same child on every page.supabase/functions/generate-audio/index.ts — long stories are chunked, synthesised in parallel and merged back into a single WAV, then cached so a re-listen costs nothing.| Layer | What we use |
|---|---|
| App | React Native 0.81 · Expo SDK 54 · expo-router · Reanimated |
| Web | The same React Native codebase, plus a static marketing site in vanilla HTML/CSS |
| Backend | Supabase Edge Functions (Deno · TypeScript) |
| Data | Postgres with Row Level Security · Supabase Auth · Storage |
| Story text | DeepSeek → Claude (via Replicate) → Groq → Gemini |
| Illustration | FLUX via fal.ai |
| Narration | FreedomSpeech (Kazakh) · Higgs TTS 3 · ElevenLabs |
| Payments | Dodo Payments (Merchant of Record) |
| Hosting | Vercel (marketing site + web app) |
mobile/ React Native + Expo app — iOS, Android and web from one codebase
landing/ Static marketing site (narrly.org), hand-written HTML/CSS, 8 languages
supabase/ Edge Functions (Deno) and SQL migrations
infra/ Self-hosted Kazakh TTS endpoint
ios-launch/ App Store assets
You will need your own API keys — none are included here, and none ever were (see below).
# 1. The app
cd mobile
npm install
cp .env.example .env.local # fill in your Supabase URL + anon key
npx expo start # press w for web, or scan the QR code
# 2. The marketing site — no build step, it is plain HTML
cd landing
python -m http.server 8000
# 3. The backend
npx supabase functions deploy generate-story
npx supabase secrets set DEEPSEEK_API_KEY=... FAL_KEY=... FREEDOMSPEECH_API_KEY=...
Only EXPO_PUBLIC_* values are read by the client. Model provider keys live exclusively
in Supabase Edge Function secrets and are never bundled into the app.
This is a public mirror of a live commercial product, published so the work can be read and reviewed. A few things are held back on purpose, and the code says so where they are:
No API key has ever been committed to this project. Secrets live in Supabase Edge Function
secrets and in a local .env.local that git has never tracked.
Live and in early access. The web app runs at app.narrly.org; Android builds ship through EAS, and iOS is in preparation.
© 2026 Narrly. All rights reserved.
The source is published for reading and review. It is not open source: you may not use, copy, modify or distribute it, in whole or in part, without written permission. See LICENSE.
Многие дети растут без простых человеческих ценностей — их воспитывает экран, а не близкий человек. Сказки же всегда были самым естественным способом что-то привить: ребёнок забудет нотацию, но запомнит героя. А чтение вместе перед сном сближает родителя и ребёнка и формирует привычку к чтению с ранних лет.
Narrly создаёт персональную иллюстрированную сказку, где главный герой — сам ребёнок, и учит одной выбранной ценности: доброте, честности, смелости. Сказку можно послушать — её озвучат голоса персонажей или голос близкого человека, чтобы даже когда мама или папа далеко, ребёнок засыпал под их голос.
Восемь языков, включая казахский с нативной озвучкой.
Сделано в Казахстане 🇰🇿