Inspiration

Every Korean app teaches you the alphabet in a day and then leaves you there. Hangul is easy to learn and hard to read: in front of a menu board in Seoul you still spell syllables one by one while the queue grows behind you. We had built two travel-language apps before (Kotomaji for Japanese, Handarin for Chinese). We came back from a trip to Korea with a handful of phrases and a lot of signs we still couldn't read, so we started studying Hangul properly and built Dalmaji while we were learning. Dalmaji (달맞이, "greeting the moon") is the app for that step: the phrases you actually say, and enough Hangul to read what's in front of you.

What it does

  • Phrasebook: 340 travel phrases in 13 situations, each with Hangul, official romanisation, an easy-reading respelling, and clear audio. A "Show it" mode turns the phone into a card you hand to the waiter.
  • Hangul in 30 minutes: all 40 letters with sound and a tappable syllable table, a six-lesson crash course (each lesson ends with real words you can now read), and a 12-sign street exam that earns you a stamp.
  • Menu Decoder: 60 dishes across five real scenes (bunsik, BBQ, jjigae, café, chimaek), each with what it is, how spicy it is and whether it has pork, seafood or is veggie-friendly, plus the phrase to order it.
  • Konglish: 90 English loanwords you already know once you can read them (커피, 아메리카노, 라떼…).
  • Won converter with 23 currencies and one-tap quick amounts; works offline with saved rates.
  • Travel guide: 72 tips in 12 sections, a 12-point checklist and a stamp collection.
  • The daily key: claiming the stamp of the day unlocks a piece of Pro content for good, with a ceiling, so coming back pays off without replacing the purchase.
  • Everything you learn works offline (buying Pro and refreshing rates need a connection), with no account, no ads and no tracking. 12 languages: English, Spanish, Simplified & Traditional Chinese, Japanese, Vietnamese, Thai, Indonesian, Malay, Russian, French and German — the app follows your device's language.

How we built it

SwiftUI, iOS 17+, @Observable, all content as JSON with unit-test invariants (counts, audio coverage for every playable id, respelling rules, the free/Pro split). Hangul syllables are composed at runtime from a small Unicode engine rather than stored. Audio is generated with ElevenLabs and level-normalised with our own scripts. Project generated with XcodeGen; store listing filled through the App Store Connect API, across all 12 languages.

How RevenueCat is used

Dalmaji is freemium with a single lifetime unlock and no subscriptions, ever. RevenueCat (purchases-ios 5.x, StoreKit 2 mode) powers the whole purchase flow:

  • One entitlement, dalmaji_pro, with two non-consumable products attached: the regular lifetime price and a welcome price shown only during the first 48 hours after the paywall is first seen.
  • The default offering carries both packages; the app picks the package to show from the offering, so the welcome window and prices can be changed from the RevenueCat dashboard without a release.
  • CustomerInfo drives every lock in the app (phrase categories, dishes, guide sections); restore purchases is one call.
  • The free/Pro split itself is remote. The offering's metadata carries a small gating policy (how many phrases per category, dishes per scene and guide sections are free, plus the daily-key ladder); the app reads it with the offering, caches it, and recomputes which items are locked. We ship 1.0 with a fairly open split and will tune it from the dashboard with real conversion data, no App Review round trip.
  • Free content is a real product, not a teaser: all essential and emergency phrases, a sample of every category, the whole alphabet, the crash course, the street exam, the 90 loanwords, the converter and the stamps stay free forever.

Challenges we ran into

  • Teaching pronunciation honestly: Korean "aspirated" consonants are best told apart by pitch, not breath, but only in the first syllable and only in Seoul speech. We measured the onset pitch of every synthesised syllable pair, regenerated the takes that didn't carry the difference, and dropped the pair no take got right.
  • Respelling that never collapses two letters: the phrasebook can write ㅓ as "o" for Spanish readers, but the alphabet can't, or 어머니 and 오머니 become the same word. Tests guard the convention.
  • Getting a full store listing (twelve locales, screenshots, pricing, availability, age rating) done through the API instead of by hand.

Accomplishments that we're proud of

An alphabet section that gets a traveller from zero to reading 출구 and 화장실 in one sitting, a paywall whose free/Pro boundary we can move from RevenueCat without shipping a build, and shipping the whole content library, phrases, dishes, tips, Konglish, in twelve languages before submitting.

What we learned

Most of what beginners are taught about Korean sounds is a simplification that breaks in the wild; the app now says the accurate thing, with its exact scope. And that the best thing to make remote-configurable isn't the price, it's what's free.

What's next

A deeper Hangul reading course, Android (the Kotomaji port is already live), more menu scenes, and a shared travel-app engine across Kotomaji, Handarin and Dalmaji.

Built With

  • app-store-connect-api
  • astro
  • elevenlabs
  • python
  • revenuecat
  • storekit
  • swift
  • swiftui
  • xcodegen
Share this project:

Updates

Submission history