GitHunt
ZE

zedsalim/sarayan

تطبيق ويب لقراءة والاستماع إلى القرآن الكريم برواي ورش عن نافع وحفص عن عاصم، لتيسير الحفظ والمراجعة.

Logo


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

Screenshots

Quran Reader - Main View   Quran Reader - Sidebar   Quran Reader - Fullscreen Mode

Features

  • 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 localStorage across sessions

Running the App

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).

1. Get the code

git clone https://github.com/zedsalim/sarayan
cd sarayan

2. Serve it locally

The 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.

Offline Audio Setup

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 in RIWAYA_CONFIG inside script.js exactly.

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.

Audio Data

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

Keyboard Shortcuts

Key Action
Space Play / Pause
ArrowLeft Next ayah
ArrowRight Previous ayah
0–9 Seek to 0%–90%
+ / - Increase / Decrease speed

Credits

Languages

HTML98.7%JavaScript0.8%CSS0.3%Python0.2%

Contributors

Created February 19, 2026
Updated March 8, 2026
zedsalim/sarayan | GitHunt