Duavara is a free React Native companion for daily Muslim prayer and worship. It calculates local prayer times from your location, shows the next prayer and Hijri date, provides Qibla guidance, and keeps selected worship progress on the device.
Released under the Apache License 2.0. See CONTRIBUTING.md to help improve the app. Read the current local privacy disclosure in PRIVACY.md.
Duavara has no subscription, in-app purchases, paid account, or API key requirement. Its network features use publicly accessible services, including AlAdhan, AlQuran.cloud, and OpenStreetMap's Overpass API. Those services are operated independently and may apply their own availability, usage, or attribution terms.
- Today: Fajr, Dhuhr, Asr, Maghrib, and Isha times, next-prayer countdown, current-prayer status, Hijri date, and sharing for today's timetable.
- Prayer accuracy and travel: named Home, Work, Mosque, Travel, and custom location profiles; Automatic calculation lets AlAdhan choose the closest supported authority from each place's coordinates, with manual community-method override, optional IANA timezone override, high-latitude rule, and per-prayer minute tuning. Each profile caches up to 30 days of schedules for offline use; the next seven days are used for native reminders.
- Qibla: a bearing from true north, a live device-compass overlay when supported, and an optional camera view. The camera view is not required for the regular bearing.
- Fasting: Monday/Thursday or alternating-day Dawud routines, Ramadan status when the returned Hijri date is in Ramadan, and optional Suhoor/Imsak reminders.
- Worship companion: mark each daily prayer as prayed, view the current streak, and use a persistent Tasbih counter with 33 or 99 targets.
- Discover: the next Hijri occasion, Islamic months, special days, and a daily reflection from the 99 Names.
- Quran: Arabic Uthmani text by surah, selectable API-provided translations, word/phrase search, and a small English related-translation helper for known topics such as
greed. Topic results are clearly labeled as related translation matches, not a curated subject index. On Android 7.1+ launchers, long-press the Duavara icon and choose Quran to open the reader directly. The reader also includes bookmarks, saved reading progress, per-ayah streamed or user-downloaded recitation, adjustable Arabic/translation type sizes, light/dark reading surfaces, RTL-aware translations, and TalkBack labels. - Nearby mosques: search OpenStreetMap for Muslim places of worship within 5 km of the active location; save favourites, record local prayer notes, and open free OpenStreetMap directions.
- Zakat calculator: calculate locally from user-entered cash, metals, business assets, debts, and selected gold or silver Nisab. Prices are entered manually; no market prices are fetched.
- Android home-screen widget: show upcoming prayer times on Android. The widget is not implemented for iOS.
Before a store release:
- Commit and publish
PRIVACY.mdunchanged or substantially unchanged at a stable public HTTPS URL (for example, themainbranch ofhttps://github.com/ivanarifin/Duavara, a project website, or a repository-owned Pages site). Use that exact URL as the Apple App Store privacy policy URL and Google Play privacy policy URL; a local repository path is not a publishable URL. - Register the Android application ID and the
id.vandev.duavaraiOS bundle ID in the relevant developer accounts. - Configure production signing outside the verification CI workflow. The verification CI workflow creates a disposable key only to prove that release artifacts can be signed; it must never be used for store uploads. The protected manual GitHub release workflow uses the production upload key from Actions secrets.
- Complete the Apple App Privacy and Google Play Data safety declarations using the disclosures in
PRIVACY.md, then review the generated store previews before submission.
No store-console configuration or submission is performed by this repository's scripts.
The Publish main preview APK workflow runs after every push to main. It signs the exact pushed commit and creates a GitHub prerelease tagged preview-<short-sha> with the APK, its .sha256 checksum, and .json provenance metadata. Preview APKs are for direct testing only and must not be submitted to Google Play.
The Publish Android APK workflow remains manual for stable releases. It builds from an immutable vX.Y.Z tag and publishes the corresponding non-prerelease GitHub Release.
- In GitHub Settings → Environments, create
previewfor automatic builds andproductionfor stable releases.previewmust not require approval. Protectproductionwith required reviewers if desired. - Add the following Actions secrets to both environments:
DUAVARA_UPLOAD_STORE_BASE64— base64-encoded Android upload.jksfile.DUAVARA_UPLOAD_STORE_PASSWORDDUAVARA_UPLOAD_KEY_ALIASDUAVARA_UPLOAD_KEY_PASSWORD
- Add a GitHub repository ruleset for
v*tags that prevents tag updates and deletion. For a stable release, updatepackage.jsonand the iOSMARKETING_VERSION, run the release checks, commit the release candidate, then create and push an annotated tag named exactlyvX.Y.Zfor that version. Open Actions → Publish Android APK → Run workflow and enter the tag plus a positive AndroidversionCodegreater than every previously published APK.
Keep the signing key and all signing credentials secret; never commit them to the repository. The workflow never overwrites an existing release tag. A GitHub Release APK is for direct distribution; build and submit a separately signed AAB for Google Play.
- Node.js
>= 22.13.0(frompackage.json) - Android development environment for Android builds, including Android SDK/NDK support for the versions configured in
android/build.gradle:- compile SDK
36 - target SDK
36 - minimum SDK
24 - NDK
27.1.12297006 - Gradle
9.4.1via the checked-in wrapper
- compile SDK
- macOS with Xcode and CocoaPods for iOS builds
- iOS deployment target
15.1 - A physical device or emulator/simulator. A device with a compass is needed for live Qibla orientation; a camera is only needed for the optional camera view.
Complete the official React Native environment setup for the platform you want to run before continuing.
From the repository root:
npm ciFor iOS, install the Ruby-managed CocoaPods dependencies after the first clone and whenever native dependencies change:
bundle install
bundle exec pod install --project-directory=iosThe repository's Gemfile pins compatible CocoaPods-related gems. If your CocoaPods workflow is already configured, bundle exec pod install from ios/ is equivalent.
In one terminal:
npm startKeep Metro running while using a debug build.
With an Android emulator running or an Android device connected:
npm run androidAndroid requests location access for device-based prayer times and true-north Qibla orientation. Notification access is requested when reminders are enabled. Camera access is optional and is requested only after opening the camera Qibla view. On Android 7.1+ launchers, long-press the Duavara icon and choose Quran to launch directly into the reader.
After installing Pods:
npm run iosThe default target is the iOS Simulator. To choose a simulator or device, use the React Native CLI options or open ios/Duavara.xcworkspace in Xcode. iOS requests location access while the app is in use and camera access only for the optional camera Qibla view.
- Open Prayer settings from the top-right menu.
- Set a location by allowing device location, or enter decimal latitude and longitude manually. Manual coordinates are useful when you do not want to grant location access.
- Save it as Home, Work, Mosque, Travel, or a custom place. Optionally add an IANA timezone, high-latitude rule, or local minute adjustments when your masjid timetable differs.
- Keep Automatic (closest authority) to let AlAdhan select from your saved place's coordinates, or choose the calculation method used by your local community; then choose the Asr juristic method (Standard or Hanafi).
- Optionally enable 24-hour time, prayer reminders, Adhan sound, and individual prayer alerts. Review Notification health to check permission, exact timing, and Android battery restrictions.
Settings, saved places, up to 30 days of per-place prayer schedules, worship records, Tasbih count, mosque favourites, Quran reading preferences, and Zakat form are stored locally with AsyncStorage. The app restores a matching saved profile timetable while offline, then refreshes it when a network connection is available.
There is no .env file, backend, API key, or project-specific runtime configuration required by the current app. The app uses these free-to-access public HTTPS services:
- AlAdhan API for prayer timings, monthly calendars, calculation methods, Automatic closest-authority selection from active-place coordinates, Qibla bearings, Hijri occasions, Islamic months, special days, and the 99 Names.
- AlQuran.cloud for the surah list, Arabic Uthmani Quran text, selectable translations, translation search, and API-provided recitation streams. The reader identifies the active translator and reciter.
- OpenStreetMap Overpass API for nearby mosque search. The app displays OpenStreetMap attribution in the results section.
- The Android or iOS platform geocoder for a best-effort nearby-region label in the header. It may use the platform's network-backed provider.
Network-backed screens show an error and can be retried if a service is unavailable. Prayer times and Qibla require coordinates; Quran and Discover load their data when opened. The Zakat calculator and worship progress do not require a network connection after the app is installed.
Calculation results are estimates based on the selected method and coordinates. Local mosque timetables or local moon-sighting decisions may differ. Ramadan dates shown by the API can differ from local moon sighting.
| Command | Purpose |
|---|---|
npm start |
Start Metro. |
npm run android |
Build and run the Android debug app. |
npm run ios |
Build and run the iOS debug app. |
npm test |
Run the Jest test suite. |
npm run lint |
Run ESLint. |
npm run bundle:apk |
Build a release APK and copy it to dist/<package-name>-<version>.apk. |
npm run bundle:aab |
Build a release Android App Bundle and copy it to dist/<package-name>-<version>.aab. |
npm run version:check |
Verify package, iOS, and Android release versions are aligned. |
npm run audit:dependencies |
Fail on unapproved dependency advisories. |
npm run version:check -- --ios-build-number 7 --android-build-code 7 validates positive release build numbers without editing native files. The equivalent environment variables are DUAVARA_IOS_BUILD_NUMBER and DUAVARA_VERSION_CODE (or DUAVARA_ANDROID_BUILD_CODE). Android bundle commands accept --version-code <positive-integer> and pass it to Gradle.
Release artifacts must be signed. On macOS, Gradle can use android/app/duavara-upload.jks and the Duavara Android Upload Keystore Keychain entry; protected release environments must provide DUAVARA_UPLOAD_STORE_FILE, DUAVARA_UPLOAD_STORE_PASSWORD, DUAVARA_UPLOAD_KEY_ALIAS, and DUAVARA_UPLOAD_KEY_PASSWORD. Never commit a keystore or its passwords. The dist/ directory is ignored by Git.
- Location: used for device-based prayer times, Qibla bearing, nearby mosques, true-north compass orientation, and a best-effort region label. Manual coordinates can be used without location permission; selected manual and saved coordinates may still be sent to the platform geocoder to resolve that label.
- Notifications: used for prayer reminders and optional fasting alarms. Up to the next seven days are scheduled. Notification health reports the current OS permission and, on Android where available, exact-alarm and battery-optimization status; Focus, Do Not Disturb, and system settings may still affect delivery.
- Camera: optional; used only by the live camera Qibla finder. The normal Qibla bearing remains available without it.
- Local storage: stores preferences, saved places, per-place 30-day caches, worship progress, Tasbih state, mosque favourites/notes, Quran reading preferences, and Zakat form data on the device. No app backend or analytics service is configured.
- Audio: the Adhan preview and notification sound use bundled CC0 audio. Quran recitation streams from AlQuran.cloud; an ayah is stored locally only after the user explicitly downloads it. Sources and license details are recorded in
THIRD_PARTY_NOTICES.md.
- Choose a new semantic version and positive, never-reused iOS build number and Android
versionCode; runnpm run version:check -- --ios-build-number <ios-build> --android-build-code <android-build-code>. - Run
npm ci,npm run audit:dependencies,npm run typecheck,npm run lint, andnpm test -- --runInBand. The audit currently documents two unpatchedimage-sizebuild-tool advisories for ICNS/JXL/HEIF parsing; Metro does not accept those formats as app assets. Reassess this exception whenever Metro orimage-sizeupdates. - Commit the reviewed release candidate, then in a protected release environment set the four
DUAVARA_UPLOAD_*variables and runDUAVARA_VERSION_CODE=<android-build-code> npm run bundle:aab. The script rejects dirty working trees so artifact metadata always identifies the committed source. Keep the AAB, checksum, metadata, and signing provenance together. Validate the published artifact withapksigner verify(APK) orjarsigner -verify(AAB; the command must reportjar verified). - Archive and export iOS with the chosen positive build number using the production signing identity; pass
CURRENT_PROJECT_VERSION=<ios-build>to the archive command, then upload artifacts through the store consoles only after reviewing the privacy URL and data disclosures.
For rollback, stop or halt the affected rollout in the store console, identify the last known-good immutable artifact and metadata, and use the store's supported rollback or staged-rollout controls. Do not reuse a build number; if a fix is needed, increment both platform build numbers, rerun validation, and release a new artifact.
Run the focused checks from the repository root:
npm test -- --runInBand
npm run lintIf prayer data does not appear, select or refresh a saved place and check network access to the AlAdhan API. If only cached data is available, the app displays up to 30 saved days for the active place and offers pull-to-refresh. If reminders show Unavailable after a rename or native-code update, reinstall the current Duavara APK—Metro reloads cannot update Kotlin modules—then enable notification permission; on Android, exact-alarm or battery settings may also be relevant. Nearby mosque search retries a second public Overpass service if the first is busy; VPNs, captive portals, or offline connections can still prevent both services from responding. If live compass guidance is unavailable, use the displayed Qibla bearing or calibrate/move the device away from metal and magnets.
For iOS native changes, reinstall Pods with bundle exec pod install --project-directory=ios. For Android native changes, a clean rebuild may be needed from Android Studio or with Gradle.
App.tsx— app shell, tabs, settings, and screen composition.src/domain/— prayer, fasting, worship, and Quran-related data rules.src/services/— API clients, location, local storage, notifications, compass, mosque search, and Android widget integration.src/components/— Quran reader, Ramadan dashboard, mosque search, Qibla camera, worship companion, and Zakat calculator.android/andios/— native application projects and native notification, compass, and widget integrations.__tests__/— Jest tests for domain rules and native-facing service behavior.