Introducing mabims-hijri: Hijri Dates, Now Offline

If you just need today’s Hijri date on your website, the REST API is great. One fetch call, parse the JSON, done.
But after building a few apps with it, I kept running into the same friction:
- Every page load hits the API. Even though the Hijri date doesn’t change every few seconds.
- Rate limits are fine, but they’re still limits. If your site gets traffic spikes, or you have multiple components all fetching the same date…
- Offline doesn’t exist. Build a PWA or a mobile app? No Hijri date without a network connection.
- Caching is your problem. You have to build your own caching layer, handle stale data, and decide TTLs.
So I built mabims-hijri, an offline-first npm package that bundles MABIMS 2024-2026 data directly in the package.
What it does
Section titled “What it does”Bundled MABIMS (2024-2026) --> Local cache --> Live API (fallback) ~70KB, built-in TTL 24h only when out of range- MABIMS 2024-2026 data is bundled inside the package (~70KB)
- When online, the SDK checks
/metafor newer data and auto-syncs - If the date is outside the bundle range, it falls back to the live API
- All
today(),convert(), andrange()operations work without internet
No API key. No registration. Just npm install.
Quick start
Section titled “Quick start”npm install mabims-hijriimport { today, convert } from 'mabims-hijri';
// Today's Hijri date, works offlineconst date = await today();console.log(`${date.output.day} ${date.output.month_name} ${date.output.year} H`);
// Convert a specific dateconst ramadhan = await convert('2026-02-19');console.log(ramadhan.output.month_name); // 'Ramadhan'That’s it. No base URL, no headers, no fetch wrappers. The data is already in your app.
SDK vs REST API: When to use which?
Section titled “SDK vs REST API: When to use which?”I still think the REST API is the right choice for many cases. Here’s how I think about it:
Use the REST API when:
- You need hilal sky charts (
/hilal/viz) - You need data beyond 2024-2026 and don’t want to bundle it
- You’re building a server-side integration where you control caching
- You want the full OpenAPI spec and code generation
Use the SDK when:
- You just need today’s date, conversion, or events in a JS/TS app
- You want offline support (PWAs, mobile apps, unreliable networks)
- You want zero-config, no fetch wrappers, no caching logic
- You’re tired of managing rate limits for the same data
For example, in a React app:
import { useState, useEffect } from 'react';import { today, type HijriDate } from 'mabims-hijri';
function HijriDate() { const [date, setDate] = useState<HijriDate | null>(null);
useEffect(() => { today().then((res) => setDate(res.output)); }, []);
if (!date) return <span>Loading...</span>; return <span>{date.day} {date.month_name} {date.year} H</span>;}No API URL to manage. No loading state to debug. Just import and use.
What’s inside the SDK
Section titled “What’s inside the SDK”| Function | What it does |
|---|---|
today() |
Today’s Hijri date, timezone-aware |
convert(date) |
Single date conversion, either direction |
range(start, end) |
Bulk conversion (max 45 days) |
month(year, month) |
All days in a month |
year(year) |
All days in a year (12 months) |
events(year) |
Islamic observances (Ramadan, Eid, etc.) |
hilal.info(month, year) |
Hilal visibility data |
All of these work offline as long as the date is within the bundled range.
React Native note
Section titled “React Native note”If you’re building a React Native app, you’ll need to set a storage adapter for persistent caching (using @react-native-async-storage/async-storage):
import { setStorageAdapter } from 'mabims-hijri';import AsyncStorage from '@react-native-async-storage/async-storage';
class RNStorage implements StorageAdapter { private prefix = 'mabims_'; async get(key: string) { return AsyncStorage.getItem(this.prefix + key); } async set(key: string, value: string) { await AsyncStorage.setItem(this.prefix + key, value); } async has(key: string) { return (await AsyncStorage.getItem(this.prefix + key)) !== null; }}
setStorageAdapter(new RNStorage());Without this, the cache resets every time the app restarts.
The bottom line
Section titled “The bottom line”If your app’s only Hijri-related need is “show today’s date in the header,” don’t build a caching layer, don’t write a fetch wrapper, and don’t worry about rate limits.
npm install mabims-hijriOne import, one function call, done, online or offline.
Full documentation at mabims.dev/en/sdk. Source on GitHub: PijarAdiluhung/mabims-hijri.
