adhan-js: high precision prayer times in Node and the browser
High precision Islamic prayer time library for JavaScript
At a glance
- What is it?
- adhan-js computes Islamic prayer times in JavaScript from the astronomical equations in Jean Meeus's Astronomical Algorithms, exposing a choice of calculation methods, a Qibla direction and Sunnah times, with native TypeScript declarations. The subtle part is not the astronomy but the time zone handling, and the library is deliberately explicit about it.
- Who is it for?
- adhan-js fits a JavaScript application that needs prayer times for a location, on a server or in a browser, and it is particularly well suited to code that already runs in TypeScript, since the declarations ship with the package and the module resolves in both ESM and CommonJS setups.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Meeus equations, and a family of libraries in other languages
Adhan JS is a library for calculating Islamic prayer times in JavaScript, running in Node or a web browser. The project describes it as well tested and well documented, and the calculation method is stated at the level of the source: all astronomical calculations are high precision equations taken directly from the book Astronomical Algorithms by Jean Meeus, a book the README says is recommended by the Astronomical Applications Department of the U.S. Naval Observatory and the Earth System Research Laboratory of the National Oceanic and Atmospheric Administration.
That matters because the prayer time for a given day and place is a derived value, and the derivation is where implementations differ. A library that states which equations it uses is a library you can reason about; one that says only that it is accurate is not.
The project is part of a family. Implementations of Adhan in other languages live in the parent repository, and the JavaScript one is published to npm as adhan, under the MIT licence with the author named as Ameir Al-Zoubi. The repository is not archived, the last push was on 2026-10-20, and the releases are frequent: v4.4.4 on 2026-06-13, v4.4.5 on 2026-08-30 and v4.4.6 on 2026-08-31.
Two of the feature claims are worth checking rather than taking on trust. The dual package support is real and visible in the metadata, with an exports map pointing at a CommonJS build, an ES module build and TypeScript declarations. The environment agnosticism claim, that it runs in Node.js, modern browsers, Bun, Deno, Next.js and Vite, is a consequence of that packaging which makes the packaging claim easier to believe on its face.
Coordinates, a date and a calculation method
The API is three objects. Coordinates holds the latitude and longitude of the location, CalculationMethod provides the parameters, and PrayerTimes combines them with a date and gives you the times back.
import { Coordinates, CalculationMethod, PrayerTimes } from 'adhan';
const coordinates = new Coordinates(35.789751, -78.691249);
const params = CalculationMethod.MoonsightingCommittee();
const prayerTimes = new PrayerTimes(coordinates, new Date(), params);
console.log(prayerTimes.fajr);The date handling has a rule that is easy to get wrong. The date parameter should be an instance of the JavaScript Date object, with the year, month and day values populated; all other values are ignored. Those values are expected to be for the date you want prayer times for, and they are expected to be for the Gregorian calendar. So a specific date is constructed with the new Date(year, month, day) form, and the time of day on that Date is irrelevant.
The calculation method is the interesting choice, and the documentation has a separate guide for it, METHODS.md, referenced as the Calculation Parameters and Methods guide. The example code uses MoonsightingCommittee, while the browser example uses NorthAmerica, and the fact that the library ships both is a hint that the method is a policy decision rather than a technical preference. Different calculation methods encode different conventions for when a prayer begins, and the settings also cover things like the angle below the horizon used for dawn, the number of days for the seven day style adjustment methods, and whether midnight is the start or the end of a prayer period.
For a CommonJS consumer the same three objects are available through require, and the library ships an ESM and a UMD browser bundle, so a page can load it from a CDN without a build step.
The output is absolute UTC, and formatting it is your job
This is the part of the library that the documentation is most emphatic about, and it is the part most likely to cause a real bug if you skip it.
The PrayerTimes object outputs raw JavaScript Date instances initialised to absolute UTC values. The warning is explicit: never assume the user's local device time zone matches the calculation coordinates. Always format prayer times with a specific time zone identifier, such as Europe/London or America/New_York, so the times display correctly and match local daylight saving time adjustments.
The recommended tool for that formatting is the native Temporal API, with a polyfill as a fallback if the target environment needs one:
Temporal.Instant.fromEpochMilliseconds(prayerTimes.fajr)
.toZonedDateTimeISO('America/New_York')
.toLocaleString('en-US', { hour: 'numeric', minute: '2-digit' });The chain reads well and each step has a job. The prayer time is a point on the universal timeline, so it becomes an instant. The instant is placed in a named zone, which is where the offset and the daylight saving rule come from. Only then is it rendered for a locale, with the format options deciding whether you want a twelve or twenty four hour clock.
A device default would be wrong in two ways at once. A traveller in a different zone from the mosque would see the local device time, and the prayer time of a place is not a property of the device. And a device that changes its zone, or a zone that changes its offset during the year, would move a prayer time that should be fixed.
The library deliberately does not do this for you, and the reason is visible in the design: it computes, and you decide how to present.
Countdowns, Sunnah times and the Qibla
Beyond the five daily prayers, the library provides the helpers an application actually needs.
The PrayerTimes object has functions for the current prayer and the next prayer, and a function for the time of a specified prayer, which makes it easy to show a countdown until the next one:
var prayerTimes = new PrayerTimes(coordinates, date, params);
var current = prayerTimes.currentPrayer();
var next = prayerTimes.nextPrayer();
var nextPrayerTime = prayerTimes.timeForPrayer(next);Sunnah times are also available. Given an instance of PrayerTimes you can get a SunnahTimes object with the times for Qiyam:
var sunnahTimes = new SunnahTimes(prayerTimes);
var middleOfTheNight = Temporal.Instant.fromEpochMilliseconds(
sunnahTimes.middleOfTheNight,
)
.toZonedDateTimeISO('America/New_York')
.toLocaleString('en-US', { hour: 'numeric', minute: '2-digit' });The Qibla direction is a single function that returns the direction, in degrees from north, of the Qibla from a given set of coordinates:
var coordinates = new Coordinates(35.78056, -78.6389);
var qiblaDirection = Qibla(coordinates);Two things are notable about these APIs. They all return the same shape of value, a timestamp that you then format yourself, so a single formatting helper covers prayers, Sunnah times and anything else in the application. And the Qibla is expressed in degrees from north rather than as a compass point, so the rounding and the display of the direction are your decision rather than the library's.
Dual packaging, a Babel and Rollup build, and the contribution rules
The build is worth a look because it explains how one source tree produces four outputs. The package manifest declares main as lib/cjs/Adhan.js, module as lib/esm/Adhan.js and types as lib/types/Adhan.d.ts, and the exports map repeats the three with a types, an import and a require condition, so a bundler and a Node resolver both find the right file.
The scripts show the machinery. The build runs the clean step and the build steps in parallel with npm-run-all, and there are separate targets for the ES module build, the CommonJS build, the browser bundles through Rollup and the type declarations through tsc. The CommonJS step writes a small package.json into the output directory with the type set to commonjs, which is the trick that lets one source tree ship both module systems without the module field confusing Node. The browser bundles come from Rollup with a Babel environment named esmBundled, and the ESM and CJS builds come from Babel with the environment names esmUnbundled and cjs.
The quality tooling is strict in a way that is worth noting. Linting runs ESLint with the flag that fails on any warning, and a separate TypeScript check with no emit. Tests run under Vitest, with a watch mode and a coverage script. The repository also has a.husky directory, a commitlint configuration, a commit message convention document in.github, and an interactive commit helper, which the contributing notes say to use instead of git commit if you are not familiar with the convention, so that changelogs can be generated automatically. A.releaserc.json configuration and a CHANGELOG.md complete the release path.
The contribution policy is specific. Feature contributions are accepted when they are documented and include appropriate unit tests, and the project is explicitly looking for contributions in the form of unit tests of prayer times for different locations, with the source of the comparison values documented.
Choosing a method, and what the library does not decide
The main decision a user of this library has to make is which calculation method to use, and the library hands you a menu rather than a default. The examples use two different ones, NorthAmerica in the browser snippet and MoonsightingCommittee in the Node snippet, and the guide for calculation parameters and methods is a separate document for a reason.
The reason is that prayer times are not a purely astronomical fact with one correct answer. The astronomical part, sun position and the angle of the sun below the horizon, is computed, and the convention part, what angle counts as dawn for a given community and how the times are rounded, is a choice. A method encodes a community's convention, so two correct implementations can differ by minutes, and an application that displays prayer times should be making that choice explicitly rather than inheriting whichever default the library happens to expose first.
The other thing the library does not do is anything with time zones beyond producing UTC timestamps, which is the correct division of labour and also the part most likely to be got wrong by a user. The documentation states the rule plainly, and following it is what separates a prayer time app that works for travellers and one that does not.
If your application is not in JavaScript, the parent Adhan repository carries implementations in other languages, and the same method parameters apply, so the choice of convention transfers even when the library does not.
Editorial conclusion
adhan-js fits a JavaScript application that needs prayer times for a location, on a server or in a browser, and it is particularly well suited to code that already runs in TypeScript, since the declarations ship with the package and the module resolves in both ESM and CommonJS setups. It is the wrong choice if your application needs a single canonical prayer time without a policy decision, because the method you pick changes the numbers, and it is the wrong choice if you want the library to handle time zones for you, since the output is absolute UTC and the formatting, including daylight saving changes, is your responsibility. Before you adopt it, read METHODS.md and choose the calculation method deliberately, format the results with a named IANA time zone rather than the device default as the documentation insists, and if you are moving from version 3, work through the migration guide, since the v4 line changed the packaging.
Frequently asked questions
What does the adhan-js library calculate?
It calculates Islamic prayer times in JavaScript for a given location and date, using high precision astronomical equations taken from Astronomical Algorithms by Jean Meeus. It also provides Sunnah times including Qiyam, the middle of the night and the last third of the night, and a Qibla direction in degrees from north.
How do I install and use adhan-js in Node?
Install it with npm install adhan, then import Coordinates, CalculationMethod and PrayerTimes, build a Coordinates object from the latitude and longitude, pick a method such as CalculationMethod.MoonsightingCommittee(), and pass them with a Date to the PrayerTimes constructor. The package ships both an ES module and a CommonJS build with an exports map, plus TypeScript declarations.
Why does adhan-js return times in UTC and how should they be displayed?
The PrayerTimes object outputs raw Date instances initialised to absolute UTC values, and the documentation warns never to assume the device time zone matches the calculation coordinates. Format the values with a named time zone identifier, using the Temporal API with a polyfill fallback, so daylight saving adjustments are handled correctly.
Where can I read about the different adhan-js calculation methods?
The methods and calculation parameters are documented separately in METHODS.md, referenced from the README as the Calculation Parameters and Methods guide. The example code uses both CalculationMethod.NorthAmerica() and CalculationMethod.MoonsightingCommittee(), and the choice reflects a convention rather than a technical preference.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/batoulapps-adhan-js)Was this useful?