Inspiration
It's 11:47pm. Something happened today. You want to tell someone. You open your phone. You scroll your contacts. There's no one to text.
You open Instagram. Everyone looks happy. You feel worse. You close it. You stare at the ceiling.
I built Out Loud for that exact moment. Not for the person who wants to "optimize their wellness routine." For the person who just needs to say the thing — and has nowhere to say it.
Every emotional app asks you to pick from a menu of approved feelings: happy, sad, anxious, grateful. Real feelings don't fit menus. The thing that hurts the most is usually the thing you can't name — or won't say out loud.
I wanted to build something that doesn't try to fix the feeling. It doesn't try to distract you from it. It just shows you that someone else is inside it too.
What it does
Out Loud is a quiet place to say the thing you can't say anywhere else.
You open the app. There's one text box: "What do you need to say?" No mood picker. No category. No dropdown. You just type.
Post it anonymously. It disappears in 24 hours. Nothing is searchable. Nothing follows you.
A stranger who feels something similar can send one sentence back. No threads. No reply chains. No way to keep escalating. Just one human sending one sentence to another human.
Core features:
- Anonymous notes — up to 500 characters, gone in 24 hours
- Resonance — tap the heart to say "I feel this too." Count is public. Identity isn't.
- One-sentence replies — the constraint is the point
- AI suggestions (Groq) — if you don't know what to say, a warm sentence is written for you. You can edit it before sending.
- Support chat — a dedicated AI chat, prompted to be warm, validating, and non-diagnostic
- Crisis safety — if a note contains crisis language, a safety screen appears before the note is displayed, with local and international helplines
- Seasonal interface — the entire palette, particle system, and tagline shift with the calendar. Spring shows petals. Summer glows. Autumn scatters leaves. Winter snows.
- Out Loud+ — an optional subscription powered by RevenueCat. The free tier stays free forever.
How we built it
Stack:
- Flutter — one codebase, iOS + Android
- Firebase Anonymous Auth — no signup, no PII, no email collection
- Cloud Firestore — real-time note feed with strict security rules
- RevenueCat (
purchases_flutter10.13.1) — in-app purchases and subscription management - Groq API (
openai/gpt-oss-120b) — fast, free-tier LLM for reply suggestions and the support chat - ai_chat_kit — drop-in chat UI for the AI support screen
- Google Fonts (Inter) — typography
- shared_preferences — device-local API key storage
Architecture decisions worth mentioning:
The seasonal particle system is drawn entirely with CustomPainter — no image assets, no animation packages. Six particle types (petals, sun motes, leaves, snowflakes, and their variants) rendered as paths, each with its own drift speed, sway amplitude, and rotation. The whole system is under 400 lines of code and adds zero KB to the APK.
The security model is Bring Your Own Key (BYOK). No API keys live in the source code. The RevenueCat key is passed at build time via --dart-define. The Groq key is entered by the user in a Settings screen and stored in device-local SharedPreferences. Anyone who clones the repo runs it with their own keys. Nothing is leaked.
Crisis detection runs before note display, not after. It's a synchronous check against a term list in the NoteCard widget's build method. If it fires, the crisis screen replaces the feed. Safety isn't a bolt-on — it's the gate.
Challenges we ran into
The Android NDK download corrupted twice. The first time, the source.properties file was missing from the extracted folder. The second time, the download just cut off mid-file. Fix was deleting both the NDK folder and the .downloadIntermediates cache — the SDK Manager was reusing the corrupted archive on every retry.
Firebase Auth returned admin-restricted-operation. This looked like a permissions bug, but it was actually that Anonymous Auth wasn't enabled in the Firebase console. The error message was the least helpful part of the whole build.
The Groq model was retired mid-build. llama-3.3-70b-versatile was shut down on August 16, 2026. The API returned this model do not have access — which reads like an API key problem, not a deprecation. Swapped to openai/gpt-oss-120b.
RevenueCat Test Store keys crash release builds. This is intentional — RevenueCat blocks release builds that use a test key so you don't accidentally ship broken payments. Had to build the demo APK in debug mode.
API key security was a real problem. The first version hardcoded the Groq key in main.dart. For a public GitHub repo, that's a leaked key. Rebuilt the entire flow around BYOK — a Settings screen, shared_preferences storage, and String.fromEnvironment for the RevenueCat key. git grep "gsk_" now returns nothing.
The seasonal system was almost abandoned. Early versions used image assets for each season's background. They looked inconsistent, loaded slowly, and made the APK large. Rewriting it as a CustomPainter with a shared palette system solved all three problems at once.
Accomplishments that we're proud of
The app actually ships. It's not a mockup. It builds to a working APK, runs on a real emulator, posts real notes to Firestore, processes real RevenueCat purchases through the Test Store, and calls Groq with real API keys.
The seasonal system has no assets. Every particle, every mountain, every snowflake is code. Four complete palettes, four particle systems, four taglines — all generated procedurally. The APK is smaller than a single stock illustration would have been.
Crisis detection is a gate, not a flag. Most apps detect crisis language and show a banner. We intercept before the content is displayed. If someone posts something dangerous, the person reading it sees resources first — not the post.
The security model is honest. No shared secret lives in the repo. A judge can clone it, run it, and use their own keys. This is how consumer apps should handle third-party API credentials, and almost none of them do.
It's genuinely quiet. No notifications. No streaks. No "you haven't opened the app in 3 days." No gamification. No dark patterns. The app does not want anything from you. That's the entire design philosophy, and it's harder to build than it sounds.
What we learned
Building for vulnerable people changes every decision. When your user might be in crisis, you can't ship the same patterns you'd use for a productivity app. Crisis detection moves to the front. The AI gets bounded prompts. The free tier stays free. The word "engagement" stops meaning anything useful.
The best features are constraints, not capabilities. One-sentence replies. 24-hour expiry. No profiles. Every one of those is a limitation, and every one makes the app better. Unlimited characters would have made notes worse. Permanent replies would have made them feel like commitments.
BYOK is underused. Every hackathon project leaks its API key. It's the easiest thing in the world to fix, and almost nobody does it because the default tutorials don't show you how.
Procedural design beats asset design for small teams. One CustomPainter file replaced six illustrations, four backgrounds, and a whole animation library. The app is smaller, faster, and more consistent because of it.
"It's 11:47pm" is a better spec than "users aged 18–24." Every design decision in this app came from thinking about one specific person in one specific moment. The moment was the product brief.
What's next for Out Loud
Short term:
- iOS release (the code is ready; just needs Apple Developer enrollment)
- The emotion resonance map — a live, anonymous, global visualisation of how people are feeling right now
- Voice notes — because sometimes a feeling doesn't have words
Medium term:
- A verified-listener tier — trained users who want to respond to people in distress, with a warm-handoff flow to local services when needed
- Private pattern insights — "you feel lonely most on Sunday nights, and it usually passes by morning." Not therapy. Just awareness.
- Localisation — Urdu, Arabic, and Spanish first
Long term:
- Partner with mental health organisations in Pakistan, the UK, and the US to keep the crisis resource list current and regionally accurate
- Open-source the crisis detection term list so other apps can reuse it
- Never add a like button. Never add a follower count. Never add a notification that exists to pull someone back.
The whole point of Out Loud is that it isn't trying to capture attention. It's trying to release it. That stays true no matter how big it gets.
Built With
- ai-chat-kit
- dart
- firebase
- firebase-auth
- firestore
- flutter
- google-fonts
- groq
- purchases-flutter
- revenuecat
- shared-preferences


Log in or sign up for Devpost to join the conversation.