Skip to content

Web + mobile app · Free · Live

Hatim App hatim.app

“Let's complete the Quran together.”

Start a khatm group with your family, your friends or your mosque community. Everyone takes a juz and marks it once read; when the ring fills, the khatm is complete. Read the Quran like a book, listen to Alafasy, pick up where you left off.

  • Next.js · Expo
  • TypeScript
  • Web · Android · iOS
  • English · Türkçe
Hatim App Quran reader: ayahs laid out like a mushaf page
Hatim App group khatm screen: the state of all 30 juz and a progress ring
  • 3Platforms on one core: web, iOS and Android
  • 52Use cases; a rule is written once, used by all three
  • 272Automated tests, including race tests on real Postgres
  • 29K+Lines of TypeScript in a single monorepo
Story

One khatm, thirty juz, one screen. No more hand-kept lists.

A group khatm is an old and beautiful tradition: in a family, a mosque or a WhatsApp group, the 30 juz of the Quran are shared out. But the list of who took which juz, and who finished, is kept by hand and gets lost between messages.

Hatim App puts it on a single screen. An admin opens a khatm, everyone taps a free juz to take it and taps "Read" when done. When someone takes a juz, every member's screen refreshes on its own; when the ring fills, the khatm is complete.

The goal is that a 60-year-old can use it without help: big buttons, plain language, and no account needed just to read. The visual language follows religious sensitivities too: only the 8-pointed star and geometric patterns, no figures of living beings, no rising-to-the-sky effects.

Allah kabul etsin
"May Allah accept it": the line on screen when the ring fills and the khatm is complete.
Group screen: open and finished khatms, members and an invite link

Two things that set it apart

01A reader like a book

The page folds from where your finger holds it

Ayahs follow the page layout of the Medina mushaf and the page turns right to left like a real book. The fold geometry and the type size that fits a page live in a shared package; web and mobile run the same engine.

  • A real page-turn recording follows the leaf: hold the page halfway and the sound pauses, let go and it fades.
  • Nine type sizes; at large sizes the page scrolls within itself and the translation grows too.
  • During recitation the ayah being read always stays visible above the player.
@hatim/book
A Quran page folding like a book

02Group khatm

Updates live, survives a double tap

When someone takes or reads a juz, every member's screen refreshes on its own. Even if two people tap the same juz at the same moment, it ends up with a single owner; pressing the same button twice breaks nothing.

  • The rule is a pure function in the core: if the same action arrives twice, the state doesn't change.
  • Row locks and conditional updates on the server; an Idempotency-Key on new records.
  • Count khatms: a target number for a surah, Ayat al-Kursi or a dhikr, with a share per member.
MarkJuzRead.ts
Group khatm screen
Content

What's inside, and what it's for

Khatm types4

  • Quran khatm30 juz

    30 juz shared across the group; the khatm is done when the ring fills.

  • Surah khatmCount

    A target count for one surah, with a share per member.

  • Ayat al-KursiCount

    A set number of recitations as a group.

  • DhikrCounter

    Salawat, istighfar, tasbih, hamd, takbir and tahlil.

Reading5

  • TranslationEN · TR

    Sahih International in English, Diyanet in Turkish; per ayah or next to the page on desktop.

  • Alafasy recitationAudio

    Plays ayah by ayah and keeps going with the screen locked.

  • Offline readingOffline

    The Quran text and translations ship inside the app.

  • Where you left offAutomatic

    The ayah you read is saved on its own and follows you across devices.

  • Bookmarks

    Mark an ayah, come back any time.

Community5

  • Public and private groupsApproved

    Anyone can find a public group; private ones are joined by request.

  • WhatsApp invite

    Tapping the link follows the group; no codes to type.

  • NotificationsPush

    New khatm, juz read, khatm completed.

  • Daily reminderScheduled

    A reading reminder at the time you choose.

  • Read without an account

    No sign-in to read; joining a group takes one step by email.

Code structure

Three apps, one rule book.

The website, the iOS/Android app and the server share the same core. A business rule is written once; neither the UI nor the server rewrites it. Dependencies only point inward, and ESLint guards the boundaries.

Layers and dependency direction

  1. @hatim/core

    Pure business rules and ports: khatm, juz, shares, groups, notifications. No React, no DOM.

    Depends on nothing

  2. @hatim/book

    The book engine: page-fold geometry, typesetting, page-turn sound.

    Depends on nothing

  3. @hatim/data

    Port implementations: API client, mock data, on-device settings and bookmarks.

    Depends on→ core

  4. api

    Bun + Hono + PostgreSQL. An endpoint only validates and calls a use case.

    Depends on→ core

  5. web

    Next.js 16 site and PWA with offline reading.

    Depends on→ core→ data→ book

  6. mobile

    Expo + React Native for iOS and Android.

    Depends on→ core→ data→ book

packages/core/src/application/use-cases/khatm/index.ts
class MemberAction<A> {
  constructor(
    private readonly ruleFn: MemberRule<A>,
    protected readonly groups: GroupRepository,
    private readonly khatms: KhatmRepository,
    private readonly session: SessionReader,
    private readonly clock: Clock,
  ) {}
  async execute(groupId: string, khatmId: string, arg: A): Promise<Khatm> {
    const user = await signedInUser(this.session);
    // Yönetici de üyelik tablosundadır
    if ((await this.groups.membership(groupId, user.id)) !== "member") throw authRequired("joinGroupFirst");
    const k = await fetchKhatm(this.khatms, groupId, khatmId);
    const updated = this.ruleFn(k, arg, { id: user.id, name: user.name }, this.clock.now());
    if (updated !== k) {
      await this.khatms.save(updated);
      await this.changed(updated, arg, user);
    }
    return updated;
  }
  protected async changed(_k: Khatm, _arg: A, _user: User): Promise<void> {}
}
The shared flow behind take, release, read and share actions. The rule is a pure function; if the state didn't change, nothing is written and no notification goes out.

Rules

  • 01

    A rule is written once

    Business rules are never rewritten in the UI or an API handler; they go into @hatim/core and all three sides use them from there.

  • 02

    Dependencies point inward

    domain → application → infrastructure → di → presentation. The UI can't reach a repository directly.

  • 03

    Double-tap safe

    Database constraints, row locks and an Idempotency-Key. If the same request arrives twice, nothing changes.

  • 04

    The core produces no text

    Errors come back as codes and the UI translates them from a dictionary. One Turkish and English dictionary, shared by web and mobile.

  • 05

    Same name, same job

    Atomic Design: Button, Sheet and KhatmScreen do the same job under the same name on web and mobile.

  • 06

    Works offline

    The Quran text and translations are bundled; on the web a service worker keeps the pages you've visited.

Tech stack

  • TypeScript
  • Bun
  • Next.js 16
  • React 19
  • Expo SDK 58
  • React Native
  • Reanimated
  • Hono
  • PostgreSQL
  • Drizzle
  • Better Auth
  • Firebase (FCM)
  • Web Push
  • Vitest
  • EAS
How it's made

Built with AI agents, under human review.

Hatim App is another example of my production setup, where I run AI agents like a team. Architecture, religious and visual rules, and the final call stay with me; repetitive work goes to the agents.

  1. Every package has its own memory

    A CLAUDE.md at the root and in every subproject: architecture, code rules, religious and visual rules. An agent reads the relevant doc instead of rescanning the project.

  2. Not done until it's seen on screen

    Web is verified in a preview and mobile in the iOS Simulator with screenshots; Android notifications were tested on a real device.

  3. One-push release

    A push to main runs tests, the build, the server deploy, a health check and a rollback on failure. Mobile ships with EAS builds and in-app updates.

  4. A video engine for Instagram

    The Hatim Reels series is rendered by its own engine: Alafasy recitation, the ayah text and a khatm progress bar at the end.

Roadmap

Done

  • hatim.app is live: site, API, email code and Google sign-in
  • A Quran reader like a book, translations, Alafasy recitation
  • Group khatm: live updates, public and private groups, invites
  • Count khatms: surah, Ayat al-Kursi and dhikr
  • Notifications: FCM, Web Push and a daily reminder
  • Android app in Google Play closed testing

Up next

  • Public release on Google Play
  • App Store and iOS notifications
  • Sign in with Apple
  • Turkish mushaf page layout
  • Learning to read the Quran

The web version is live and free at hatim.app. The Android app is in closed testing on Google Play and the iOS version is not in the store yet. The source code lives in a private repository.

Let's build one

Got an app in mind?

I build web, iOS and Android from a single codebase, from the idea all the way to the stores. Let's talk about your idea in 15 minutes.