npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@calgiellc/quran

v1.0.2

Published

Complete Quran library with text and audio support. Access all 114 surahs with multiple reciters and audio URLs.

Downloads

456

Readme

@calgiellc/quran

A comprehensive TypeScript library that provides complete Quran text and audio data. Access all 114 surahs with multiple reciters and audio URLs.

Features

  • 📖 Complete Quran Text: All 114 surahs with 6,236 ayahs
  • 🎙️ Multiple Reciters: Support for 10+ reciters from mp3quran.net
  • 🔍 Powerful Search: Search in Arabic text and translations
  • 🎯 Filtering: Filter by revelation type, surah range, and more
  • 📄 Pagination: Built-in pagination support for large datasets
  • Performance: Optimized with caching and efficient data structures
  • 🎨 Type-Safe: Full TypeScript support with comprehensive types
  • 📦 Zero Dependencies: No runtime dependencies
  • 🌳 Tree-Shakeable: Optimized for bundle size

Installation

npm install @calgiellc/quran

React Hook (Optional)

If you're using React, you can also use the optional hook:

npm install @calgiellc/quran react

Then import from the hooks path:

import { useQuran } from '@calgiellc/quran/hooks';

Quick Start

Simple 3-Step Workflow (Recommended)

import { createQuran, createQuranSession } from '@calgiellc/quran';

// Step 1: Get all reciters and let user pick
const quran = createQuran();
const reciters = quran.getAllReciters();

// Step 2: Create session with user's picked reciter
const session = createQuranSession('alzain');

// Step 3: Get surahs and play!
const surahs = session.surahs; // All surahs for this reciter
const { audioUrl, fullText, surah } = session.getPlayerData(1); // Everything to play surah 1

Basic Usage

import { createQuran } from '@calgiellc/quran';

// Create a Quran instance
const quran = createQuran();

// Get all surahs
const surahs = quran.getAllSurahs();
console.log(`Total surahs: ${surahs.length}`); // 114

// Get a specific surah
const alFatiha = quran.getSurah(1);
console.log(alFatiha?.nameTransliterated); // "Al-Fatiha"

// Get a specific ayah
const firstAyah = quran.getAyah(1, 1);
console.log(firstAyah?.text); // Arabic text
console.log(firstAyah?.translations?.en); // English translation

API Documentation

Core Methods

getAllSurahs(): Surah[]

Get all 114 surahs sorted by number.

getSurah(number: number): Surah | null

Get a specific surah by number (1-114).

getAyah(surahNumber: number, ayahNumber: number): Ayah | null

Get a specific ayah by surah and ayah number.

getSurahs(filters?: FilterOptions): Surah[]

Get surahs with optional filters.

getSurahsPaginated(pagination?: PaginationOptions, filters?: FilterOptions): PaginatedResult<Surah>

Get paginated surahs with optional filters.

Reciter Methods

getAllReciters(): Reciter[]

Get all available reciters.

getReciter(reciterId: string): Reciter | null

Get a specific reciter by ID.

getSurahsByReciter(reciterId: string): Surah[]

Get all surahs available for a specific reciter.

Audio Methods

getAudioUrl(reciterId: string, surahNumber: number, ayahNumber: number): string | null

Get audio URL for a specific ayah.

getSurahAudioUrls(reciterId: string, surahNumber: number): AudioUrl[]

Get all audio URLs for a surah.

getSurahAudioUrl(surahNumber: number): string | null

Get audio URL for a surah using the preferred reciter (for mp3 players).

getSurahAudioUrlForReciter(reciterId: string, surahNumber: number): string | null

Get audio URL for a surah for a specific reciter.

getSurahFullText(surahNumber: number): string | null

Get full text of a surah with ayah separators.

Preferred Reciter Methods

setPreferredReciter(reciterId: string): void

Set the preferred reciter for convenience methods.

getPreferredReciter(): Reciter | null

Get the preferred reciter.

getPreferredReciterId(): string | null

Get the preferred reciter ID.

clearPreferredReciter(): void

Clear the preferred reciter.

getPreferredReciterSurahs(): Surah[]

Get surahs available for the preferred reciter.

Search Methods

search(query: string, options?: SearchOptions): SearchResult[]

Search the Quran text.

searchPaginated(query: string, pagination?: PaginationOptions, options?: Omit<SearchOptions, 'limit'>): PaginatedResult<SearchResult>

Get paginated search results.

Examples

Filtering

// Filter by revelation type
const meccanSurahs = quran.getSurahs({ revelationType: 'meccan' });
const medinanSurahs = quran.getSurahs({ revelationType: 'medinan' });

// Filter by surah number range
const firstTen = quran.getSurahs({ 
  minSurahNumber: 1, 
  maxSurahNumber: 10 
});

// Filter by number of ayahs
const shortSurahs = quran.getSurahs({ maxAyahs: 50 });

// Combine filters
const filtered = quran.getSurahs({ 
  revelationType: 'meccan',
  minSurahNumber: 1,
  maxSurahNumber: 30,
  maxAyahs: 100
});

Pagination

// Get paginated surahs
const page1 = quran.getSurahsPaginated({ page: 1, pageSize: 10 });
console.log(page1.items); // First 10 surahs
console.log(page1.hasNext); // true
console.log(page1.totalPages); // 12

// Get next page
const page2 = quran.getSurahsPaginated({ page: 2, pageSize: 10 });

// Pagination with filters
const meccanPage = quran.getSurahsPaginated(
  { page: 1, pageSize: 20 },
  { revelationType: 'meccan' }
);

Search

// Basic search
const results = quran.search('mercy', { language: 'en' });

// Search with filters
const filteredResults = quran.search('Allah', {
  language: 'en',
  filters: { revelationType: 'meccan' }
});

// Paginated search
const searchPage = quran.searchPaginated(
  'Allah',
  { page: 1, pageSize: 10 },
  { language: 'en' }
);

Working with Reciters

// Get all reciters
const reciters = quran.getAllReciters();

// Get audio URL
const audioUrl = quran.getAudioUrl('alzain', 1, 1);
// Returns: "https://www.mp3quran.net/eng/alzain/1"

// Get all audio URLs for a surah
const audioUrls = quran.getSurahAudioUrls('alzain', 1);
audioUrls.forEach(audio => {
  console.log(`Ayah ${audio.ayahNumber}: ${audio.url}`);
});

Using Full Text

const surah = quran.getSurah(1);
if (surah?.fullText) {
  // fullText contains all ayahs with separators: "text [1] text [2] ..."
  console.log(surah.fullText);
}

// Or use the convenience method
const fullText = quran.getSurahFullText(1);

Simple Session API (Recommended)

The easiest way to work with a reciter - perfect for your workflow:

import { createQuranSession } from '@calgiellc/quran';

// 1. Get all reciters and let user pick
const quran = createQuran();
const reciters = quran.getAllReciters();

// 2. Create session with user's picked reciter (one line!)
const session = createQuranSession('alzain');

// 3. Get surahs for this reciter
const surahs = session.surahs; // All surahs available

// 4. Get everything to play a surah (one call!)
const { audioUrl, fullText, surah } = session.getPlayerData(1);
// <audio src={audioUrl} controls />
// <div>{fullText}</div>

Alternative: Preferred Reciter Workflow

If you prefer the full API:

// 1. Get all reciters and let user pick
const quran = createQuran();
const reciters = quran.getAllReciters();

// 2. Initialize with preferred reciter
const quranWithReciter = createQuranWithReciter('alzain');
// Or set it later
quran.setPreferredReciter('alzain');

// 3. Get surahs for preferred reciter
const surahs = quran.getPreferredReciterSurahs();

// 4. Get audio URL for mp3 player
const audioUrl = quran.getSurahAudioUrl(1);
// <audio src={audioUrl} controls />

// 5. Get full text while audio plays
const fullText = quran.getSurahFullText(1);

React Hook (Optional)

import { useQuran } from '@calgiellc/quran/hooks';

function QuranPlayer() {
  const {
    quran,
    preferredReciter,
    setPreferredReciter,
    getSurahsForReciter,
    getSurahAudioUrl,
    getSurahFullText,
  } = useQuran('alzain'); // or useQuran() and set later

  const surahs = getSurahsForReciter();
  const audioUrl = getSurahAudioUrl(1);
  const fullText = getSurahFullText(1);

  return (
    <div>
      <select onChange={(e) => setPreferredReciter(e.target.value)}>
        {quran.getAllReciters().map(r => (
          <option key={r.id} value={r.id}>{r.name}</option>
        ))}
      </select>
      <audio src={audioUrl} controls />
      <p>{fullText}</p>
    </div>
  );
}

Error Handling

import { QuranError, QuranErrorCode } from '@calgiellc/quran';

try {
  const surah = quran.getSurah(1);
  const audioUrl = quran.getAudioUrl('invalid-reciter', 1, 1);
} catch (error) {
  if (error instanceof QuranError) {
    switch (error.code) {
      case QuranErrorCode.INVALID_SURAH_NUMBER:
        console.error('Invalid surah number');
        break;
      case QuranErrorCode.RECITER_NOT_FOUND:
        console.error('Reciter not found');
        break;
      case QuranErrorCode.AUDIO_URL_NOT_FOUND:
        console.error('Audio URL not found');
        break;
      default:
        console.error('Error:', error.message);
    }
  }
}

Performance

The library is optimized for performance:

  • Caching: Results are cached for frequently accessed data
  • Efficient Lookups: O(1) Map-based lookups for surahs
  • Lazy Evaluation: Data is loaded only when needed
  • Tree-Shaking: Unused code is eliminated in production builds

Expected performance:

  • getAllSurahs(): < 1ms (cached after first call)
  • getSurah(): < 0.1ms (Map lookup)
  • getSurahs() (filtered): < 1ms (cached)
  • search(): < 100ms (depends on query)
  • getSurahsPaginated(): < 1ms

TypeScript Support

Full TypeScript support with comprehensive types:

import type { 
  Surah, 
  Ayah, 
  Reciter, 
  FilterOptions,
  PaginationOptions,
  PaginatedResult,
  SearchOptions,
  SearchResult 
} from '@calgiellc/quran';

Data Structure

Surah

interface Surah {
  number: number; // 1-114
  name: string; // Arabic name
  nameTransliterated: string; // Romanized name
  nameTranslated?: { [language: string]: string };
  numberOfAyahs: number;
  revelationType: 'meccan' | 'medinan';
  ayahs: Ayah[];
  fullText?: string; // Full surah text with ayah separators
}

Ayah

interface Ayah {
  number: number; // Ayah number within surah
  text: string; // Arabic text
  textSimple?: string;
  transliteration?: string;
  translations?: { [language: string]: string };
}

Reciter

interface Reciter {
  id: string;
  name: string;
  nameArabic?: string;
  audioFormat: 'mp3' | 'm4a' | 'ogg';
  audioBaseUrl: string;
  language?: string; // For mp3quran.net format
  urlName?: string; // For mp3quran.net format
  surahs: number[]; // Available surah numbers
}

Contributing

Contributions are welcome! Please read our contributing guidelines before submitting PRs.

License

MIT

Support

For issues, questions, or contributions, please visit our GitHub repository.

Acknowledgments

quran-npm