Building a simple clock to calculate the Islamic call to prayer (Adhan) seems straightforward at first. Since the timing of the five daily prayers is based entirely on the position of the sun, you just need a bit of astronomy, right?
Well, yes. But if you try to build a production app, you quickly realize that astronomy is easy, but geography is hard.
In this tutorial, we will look at how to calculate prayer times using TypeScript, investigate the geographical edge cases that break naive implementations, and look at an open-source mapping engine we built to solve them.
Step 1: The Basic Calculations (The Easy Part)
At the core, you need to calculate solar declination based on a user's latitude and longitude. Instead of recreating NASA-level math from scratch, the brilliant adhan.js library handles the astronomy perfectly.
Let's assume we want to get the prayer times for London, UK:
import { Coordinates, CalculationMethod, PrayerTimes } from 'adhan';
// London, UK Coordinates
const londonCoords = new Coordinates(51.5074, -0.1278);
const date = new Date(); // Today
// We must choose a calculation method.
// For London, the "Muslim World League" is largely standard.
const params = CalculationMethod.MuslimWorldLeague();
const prayerTimes = new PrayerTimes(londonCoords, date, params);
console.log('Fajr:', prayerTimes.fajr);
console.log('Maghrib:', prayerTimes.maghrib);
Simple, right? Run this, and you get incredibly precise times. However, this implementation will fail spectacularly if you try to scale it.
Step 2: The Geographical Nightmare
Did you notice this line?
const params = CalculationMethod.MuslimWorldLeague();
There are over a dozen authoritative mathematical models globally for calculating the angles for Fajr (Dawn) and Isha (Night).
If a user opens your app in New York, they expect the ISNA (Islamic Society of North America) method. If they open it in Makkah, they expect the Umm Al-Qura fixed-interval method. If they open it in Karachi, they expect the University of Islamic Sciences method, plus a different "school of thought" adjustment (Hanafi) for the Asr (Afternoon) prayer.
If you just default everyone to MuslimWorldLeague(), your times will be off by up to 45 minutes in certain parts of the world. Your users will uninstall your app immediately.
Step 3: The Solution (Intelligent Mapping)
You cannot ask users "Hey, do you follow the ISNA or the Egyptian General Authority rules?" because 99% of people have no idea. They just know when their local mosque calls the Adhan.
To solve this, your application needs an intelligent mapping layer that takes the user's location and automatically assigns the correct calculation parameters.
When building Islamic Hotspot (a platform providing times for 500+ global cities), we spent weeks manually mapping 100+ ISO country codes to their exact calculation parameters.
Instead of forcing you to do that research from scratch, we open-sourced our entire TypeScript mapping engine.
You can drop the islamic-prayer-times-utility package right into your Node project:
npm install islamic-prayer-times-utility
Now, instead of guessing the method, you can dynamically assign it based on the user's country code:
import { getCalculationMethodForCountry, getMethodName } from 'islamic-prayer-times-utility';
// If a user in Saudi Arabia connects:
const saudiMethod = getCalculationMethodForCountry('SA');
console.log(getMethodName(saudiMethod)); // "Umm Al-Qura (Makkah)"
// If a user in the US connects:
const usMethod = getCalculationMethodForCountry('US');
console.log(getMethodName(usMethod)); // "ISNA"
By putting this utility in front of your calculations, your app instantly becomes hyper-accurate globally.
Bonus: The Lunar Calendar Offset
The second major headache is dates. The Hijri (Islamic) calendar is lunar. While libraries like hijri-converter can do the math perfectly for the standard Tabular calendar (which Saudi Arabia uses), they fail regionally.
Countries in North Africa (like Morocco, Algeria, and Tunisia) strictly follow physical local moon sightings. This means their calendar is frequently one day behind the mathematically predicted Tabular calendar.
Our open-source wrapper handles this automatically as well:
import { gregorianToHijriDateForCountry } from 'islamic-prayer-times-utility';
const date = new Date();
// Getting the Hijri date in Morocco (Automatically handles the -1 day offset!)
const moroccanHijri = gregorianToHijriDateForCountry(date, 'ma');
console.log(moroccanHijri.formatted); // Outputs accurately localized date
Summary
Building localized applications requires moving beyond standard math into cultural and geographical research.
If you are building an Islamic app, I highly recommend using adhan.js for your astronomy, and our mapping engine to handle the geography.
- The Mapping Engine (Open Source): islamic-prayer-times-utility on GitHub
- See this code running in Production: IslamicHotspot.com
Have you ever run into weird geolocation edge cases while building apps? Let me know in the comments!
Top comments (0)