
In our last post, we laid out the three principles behind Crolingo. Principles are one thing — execution is another. Here's the technical behind-the-scenes: six development phases, the concrete stack, trade-offs, and what broke.
The first prototype: flashcards, multiple choice, a streak counter. Classic gamification. Wafa used it for two weeks, then stopped. The problem wasn't the tech — it was that she felt no progress toward a concrete goal: the A1.1 HEP exam required to renew her residence permit.
An XP score means nothing when you need to order pizza over the phone. People don't learn a language for gamification — they learn it for real-life situations.
We threw out lessons like "Lesson 5: Adjectives." Instead: "Scenario: talking to your landlord," "Scenario: ordering at a restaurant." Every scenario is a dialogue that actually happened.
The user walks through the dialogue, listens, repeats, and the AI mentor corrects them. Supabase with JSON fields for dialogues — flexible enough for frequent edits. EU region Frankfurt, because GDPR isn't optional; it's the baseline.
Language learning doesn't work without listening and speaking. We recorded native speakers in Split — not generic recordings, but the local accent. A waitress in Diocletian's Palace doesn't talk like an HRT newsreader. That accent matters.
For speech recognition: OpenAI Whisper API. Google Speech-to-Text was the alternative, but Whisper handles Croatian more accurately. For AI feedback: Anthropic Claude. GPT-4 was too verbose; Claude gives more concise corrections that are easier to retain.
Trade-off: API costs scale with users. Every audio request costs money. We solved it with caching on Supabase Storage for frequently used phrases and rate limiting (max 50 requests per day on the free tier).
Result: within six weeks, Wafa could order pizza over the phone.
Most language apps offer an interface in 1–2 languages. Crolingo needs 24, because our users come from all over the world. If you're learning Croatian and your native language is Arabic, the interface has to be in Arabic.
Stack: next-intl (React internationalization library) + JSON files for translations + dynamic native language detection via browser locale and user preference. RTL support for Arabic and Farsi (Tailwind directionality utilities).
Wafa was our first tester — Arabic, French, and English in parallel. She found 14 bugs where Arabic text overlapped with buttons. Test on a real RTL user account, not just by flipping CSS.
We needed iOS and Android. A team of three can't maintain two native codebases (Swift and Kotlin). React Native was an option, but the Next.js stack was already in place.
The choice: Capacitor + Next.js + React Server Components. One codebase, two apps. Capacitor wraps the Next.js app in a native container with access to native APIs (microphone, notifications, storage).
Trade-off: it's slightly slower than true native. Animations aren't quite as smooth. But iteration speed is 5x — we deploy a fix to web, iOS, and Android at once. For a team of three, that's the difference between shipping a feature in a week or a month.
What broke: the OAuth flow on Android (we use Magic Link). Capacitor opens the email link in an external browser and the token is lost. We solved it with custom deep link handling and session cookie sharing between the browser and app context. One hour of debugging, one line of code to fix.
Three hotels in Split reached out: "Can we buy a package for 30 workers?" It wasn't planned, but the market was asking.
We're building a B2B layer: an admin dashboard for employers (overview of all users in the organisation), group licensing (bulk purchasing via Stripe Checkout), progress tracking, and certificates for HZZ. Launch planned for 2026.
Stack extension: Supabase Row Level Security for multi-tenancy (each organisation sees only its own users), Stripe webhooks for automatic licence assignment, PDF generation for certificates (react-pdf).
Frontend: Next.js 16 (App Router + RSC), Tailwind CSS, next-intl
Backend: Supabase (Postgres + Auth + Storage), EU region Frankfurt
AI: OpenAI Whisper API, Anthropic Claude
Mobile: Capacitor (iOS + Android wrapper)
Payment: Stripe Checkout + webhooks
Hosting: Vercel (auto-scaling, EU edge)
Every technology was chosen for a concrete reason, not because it was hyped. Next.js for SSR + RSC + mobile via Capacitor. Supabase for Postgres with built-in auth and EU hosting. Whisper because it handles Croatian better than Google. Claude because it's more concise than GPT.
Next up — stories from our first users. What they taught us about what actually matters to them.
Need help with a project?
Talk to us — directly, no sales pitch.