English | العربية
A lightweight, offline/online-friendly Mushaf web app (Arabic / RTL) supporting both Warsh and Hafs riwayas. Browse the Qur'an by Surah, Juz', or Page and listen verse-by-verse audio with full playback controls.
🌐 Live site: sarayan.pages.dev 📦 Android APK: Download from Releases
- Two riwayas: switch between Warsh (رواية ورش عن نافع) and Hafs (رواية حفص عن عاصم) instantly — click the badge in the header or use the sidebar selector
- Navigate by Surah, Juz, Page, or Ayah from a sidebar
- Verse-by-verse audio playback with multiple reciters per riwaya
- Play modes: ayah, page, surah, or juz
- Playback speed (0.5×–2×) and repeat controls (including infinite)
- Adjustable Qur'an text font size
- Active ayah highlighting with auto-scroll
- Toggle fullscreen reading mode
- Settings persist via
localStorageacross sessions
You can use the app in three ways:
- Online (no setup): visit sarayan.pages.dev directly in your browser.
- Android: download and install the APK from Releases (enable "Install from unknown sources" if prompted).
- Locally: clone the repo and serve it yourself (required for offline audio).
git clone https://github.com/zedsalim/sarayan
cd sarayanThe app must be served over HTTP — opening index.html directly won't work. Pick any of these:
# Python 3
python -m http.server 3000
# Python 2
python -m SimpleHTTPServer 3000
# Node.js (npx)
npx serve .
# VS Code
# Install the "Live Server" extension and click "Go Live"Then open http://localhost:3000 in your browser.
By default the app streams audio from online URLs. To use it fully offline, download the audio files and place them locally under the correct riwaya subfolder:
1. Download the audio files
Download the reciter folder(s) from Google Drive: 📁 Download Audio — Google Drive
2. Place them in the right folder
Audio is organised by riwaya:
audio_local/
├── warsh/
│ └── reciter_name/ ← Warsh reciter folder
│ ├── 001/
│ │ ├── 001.mp3
│ │ ├── 002.mp3
│ │ └── ...
│ ├── 002/
│ └── ...
└── hafs/
└── reciter_name/ ← Hafs reciter folder
├── 001/
│ ├── 001.mp3
│ └── ...
└── ...
⚠️ Folder names must match the reciter keys defined inRIWAYA_CONFIGinsidescript.jsexactly.
3. Run the local server and enjoy offline
The app automatically detects whether local audio files are present (via a single HEAD request per surah) and uses them. If they're missing it falls back to streaming online. No configuration needed.
Online audio is split into per-reciter, per-surah chunk files for lazy loading, generated by scripts/split_reciters.py:
assets/audio_cloud/
├── warsh/
│ └── lazy/
│ └── reciter_name/
│ ├── index.json ← list of available surahs
│ ├── 001.json
│ ├── 002.json
│ └── ...
└── hafs/
└── lazy/
└── reciter_name/
├── index.json
├── 001.json
└── ...
Each surah chunk contains CDN account/token pairs the app uses to reconstruct audio URLs at runtime. To regenerate:
python split_reciters.py --scan assets/audio_cloud| Key | Action |
|---|---|
Space |
Play / Pause |
ArrowLeft |
Next ayah |
ArrowRight |
Previous ayah |
0–9 |
Seek to 0%–90% |
+ / - |
Increase / Decrease speed |
- Qur'an text & fonts: King Fahd Glorious Qur'an Printing Complex (KFGQPC)
- Warsh font:
uthmanic_warsh_v21.ttf(KFGQPC Warsh Uthmanic script) - Hafs font:
uthmanic_hafs_v20.ttf(KFGQPC Hafs Uthmanic script)
- Warsh font:
- Audio: mp3quran.net, VerseByVerseQuran.com, EveryAyah.com, QuranPedia.net
- UI framework: Bootstrap 5 RTL


