Gregorian โ Hijri (Umm al-Qura) calendar conversion for React Native using native OS APIs.
- ๐ iOS:
NSCalendar.islamicUmmAlQura - ๐ค Android:
java.time.chrono.HijrahChronology
โ
No JavaScript math
โ
No lookup tables
โ
Zero dependencies
โ
TypeScript support
- React Native 0.76+ (New Architecture / TurboModules)
- iOS 13+
- Android API 24+
npm:
npm install hijri-nativeyarn:
yarn add hijri-nativebun:
bun add hijri-nativeimport {
toHijri, // Gregorian โ Hijri
toGregorian, // Hijri โ Gregorian
fromTimestamp, // Unix timestamp โ Hijri
getDaysInMonth, // Get days in Hijri month
today, // Today's Hijri date
} from 'hijri-native';
// Gregorian โ Hijri
const hijri = toHijri(2026, 2, 18);
// { year: 1447, month: 8, day: 20 }
// Hijri โ Gregorian
const greg = toGregorian(1447, 8, 20);
// { year: 2026, month: 2, day: 18 }
// Unix timestamp (seconds) + timezone โ Hijri
const hijriNow = fromTimestamp(Math.floor(Date.now() / 1000), 'Asia/Riyadh');
// Today's Hijri date in a timezone
const todayHijri = today('Asia/Riyadh');
// Days in a Hijri month (29 or 30)
const days = getDaysInMonth(8, 1447);import {
isEqual,
isBefore,
isAfter,
differenceInDays,
addDays,
} from 'hijri-native';
const a = { year: 1447, month: 8, day: 20 };
const b = { year: 1447, month: 9, day: 1 };
isEqual(a, b); // false
isBefore(a, b); // true
isAfter(a, b); // false
differenceInDays(a, b); // ~10
addDays(a, 5); // { year: 1447, month: 8, day: 25 }isEqual, isBefore and isAfter are pure TypeScript and need no native
module. Import them from hijri-native/pure to use them anywhere โ tests, server
code, web bundles โ with no native dependency at all:
import { isEqual, isBefore, isAfter } from 'hijri-native/pure';Importing this package is side-effect free: the native module is resolved with
TurboModuleRegistry.get, so nothing throws until you call a conversion
function. A test that merely imports a module which re-exports hijri-native
therefore needs no mock.
To exercise the conversion functions themselves, mock the package:
jest.mock('hijri-native', () => ({
today: () => ({ year: 1447, month: 8, day: 20 }),
toHijri: () => ({ year: 1447, month: 8, day: 20 }),
toGregorian: () => ({ year: 2026, month: 2, day: 8 }),
}));Use isAvailable() to branch at runtime where the native module may be missing:
import { isAvailable, today } from 'hijri-native';
const hijri = isAvailable() ? today('Asia/Riyadh') : null;import type { HijriDate } from 'hijri-native';
// { year: number; month: number; day: number }| Feature | hijri-native | JS Libraries |
|---|---|---|
| Accuracy | โ Native OS APIs | |
| Performance | โ Native speed | |
| Bundle size | โ Zero deps | |
| Umm al-Qura | โ iOS & Android |
MIT ยฉ Fahad