Open-source Quran recitation app for iOS and Android
Bayaan lets you listen to Quran recitations from 200+ reciters with background audio support, a full Uthmani Mushaf, Adhkar, offline downloads, playlists, and ambient sounds.
- Quran Player — Stream or download recitations from 200+ reciters across multiple rewayat. Background playback, lock screen controls, sleep timer, playback speed, and repeat modes.
- Digital Mushaf — Full Uthmani text rendered with Digital Khatt using Skia. Verse follow-along synced to audio playback, multiple reading themes.
- Multi-Qira'at (Rewayat) — All 8 canonical KFGQPC rewayat selectable from settings (Hafs, Shu'bah, Al-Bazzi, Qunbul, Warsh, Qalun, Al-Duri, Al-Susi). Published-mushaf-style highlighting for differences from Hafs; context flows into player text, share surfaces, and saved annotations.
- Adhkar — Comprehensive collection of daily Adhkar and Du'a with audio, counters, and saved favorites.
- Offline Downloads — Download any reciter's complete Quran for offline playback. Persistent download management with progress tracking.
- Playlists — Create and manage custom playlists backed by SQLite.
- Ambient Sounds — Layer nature sounds (rain, ocean, forest, etc.) over recitation audio.
- Search — Fast fuzzy search across reciters and surahs using Fuse.js.
- Translations & Tafseer — Multiple translation languages and tafseer editions, downloadable for offline use.
- Word-by-Word — Arabic word-by-word translation overlay in the Mushaf view.
- Themes — Light and dark mode with multiple Mushaf reading themes.
- i18n — Internationalisation via react-i18next with RTL support.
| Layer | Technology |
|---|---|
| Runtime | React 19 + React Native 0.83 + Expo SDK 55 |
| Language | TypeScript 5.9 (strict) |
| Navigation | Expo Router (file-based, v55) |
| Audio | expo-audio with background playback |
| Mushaf rendering | @shopify/react-native-skia 2.2 (Digital Khatt) |
| State management | Zustand |
| Local database | expo-sqlite (SQLite + FTS5) |
| Fast key-value storage | react-native-mmkv |
| Lists | @shopify/flash-list |
| Animations | react-native-reanimated 4 + react-native-worklets |
| Images | expo-image |
| Search | fuse.js (client-side fuzzy search) |
| i18n | react-i18next with RTL support |
| Backend (optional) | Bayaan REST API (Hono/Bun on Railway); Supabase is legacy |
| Observability (opt-in) | Sentry + PostHog (both disabled when env keys absent) |
flowchart TD
AppInitializer["AppInitializer\n(startup orchestrator)"] --> CriticalServices
AppInitializer --> NonCriticalServices
subgraph CriticalServices ["Critical (sequential)"]
DB["DatabaseService\n(SQLite)"]
Playlists["PlaylistService"]
DB --> Playlists
end
subgraph NonCriticalServices ["Non-critical (parallel)"]
ExpoAudio["ExpoAudioService\n(singleton)"]
Mushaf["MushafPreloadService\n(Skia + fonts)"]
Timestamps["TimestampDatabaseService"]
Translations["TranslationDbService"]
Stores["Store hydration\n(Zustand)"]
end
ExpoAudio --> ExpoAudioProvider["ExpoAudioProvider\n(React bridge)"]
ExpoAudioProvider --> PlayerStore["playerStore\n(Zustand)"]
PlayerStore --> UI["Player UI\nFloatingPlayer / MiniPlayer"]
For a full architecture walkthrough see docs/architecture/current-state.md.
- Node.js 20+
- For iOS: macOS with Xcode 15+ and Ruby (for CocoaPods, ships with macOS)
- For Android: Android Studio with an emulator, JDK 17+
Expo CLI is bundled with the project — invoke it via npx expo rather than installing globally.
git clone https://github.com/thebayaan/Bayaan.git
cd Bayaan
npm installcp .env.example .envThe app runs out of the box with bundled reciter data — no keys required. See CONTRIBUTING.md for the full list of optional variables (backend API, analytics, Sentry, deep links, OTA updates).
# Start the Expo dev server
npm start
# Run on iOS simulator (macOS only)
npm run ios
# Run on Android emulator
npm run androidBayaan/
├── app/ # Expo Router screens
│ ├── (tabs)/ # Main tab navigator
│ │ ├── (a.home)/ # Home tab
│ │ ├── (b.search)/ # Search tab
│ │ ├── (b.surahs)/ # Surahs tab
│ │ ├── (c.collection)/ # Collection tab (downloads, playlists, etc.)
│ │ └── (d.settings)/ # Settings tab
│ ├── share/ # Deep link share targets
│ └── mushaf.tsx # Full-screen Mushaf reader
├── components/ # Reusable UI components
├── services/ # Business logic and service singletons
│ ├── audio/ # ExpoAudioService, ExpoAudioProvider, AmbientAudioService
│ ├── player/ # playerStore, downloadStore, and player utilities
│ ├── mushaf/ # Digital Khatt rendering services
│ ├── database/ # SQLite service wrappers
│ └── AppInitializer.ts # App startup orchestrator
├── store/ # Zustand stores (24 modules)
├── types/ # TypeScript type definitions
├── constants/ # App-wide constants
├── hooks/ # Custom React hooks
├── data/ # Static data (reciters.json, surahs.json)
├── assets/ # Fonts, images, audio
└── docs/ # Full documentation
Full documentation lives in the [docs/](docs/README.md) directory:
- Architecture overview
- Player system
- Digital Khatt / Mushaf
- Downloads
- Deployment guide
- Contributing guide
- Self-hosting
Contributions are welcome. Please read CONTRIBUTING.md before opening a pull request.
Key points:
- Branch off
develop, nevermain - Run
npx prettier --writeandnpx tsc --noEmitbefore submitting - Test on both iOS and Android
Bayaan is open source under the GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later).
In plain English:
- You are free to use, study, modify, and redistribute this code.
- If you run a modified version as a network service, you must make your modified source code available to users of that service.
- Any fork or derivative must be licensed under AGPL-3.0-or-later as well.
- "Bayaan" and the Bayaan logo are trademarks and are not licensed under AGPL. Forks must rebrand before distribution. See TRADEMARKS.md for details.
See LICENSE for the full terms.
Coming soon — contributions welcome.
Built with care for the Muslim community.