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

@luraty/pack-ar-x-quran

v0.1.1

Published

Qur'anic Arabic language pack for @luraty/engine — 10,850 lemmas ranked by Qur'anic frequency, 90,549 surface forms including mushaf spellings.

Readme

@luraty/pack-ar-x-quran

Qur'anic Arabic, as a LanguagePack the engine can run.

import { arQuran, vocabulary } from '@luraty/pack-ar-x-quran';

9,598 lemmas ranked by how often they occur in the Qur'an, and 90,549 surface forms that key onto them. The corpus is a single closed text, so unlike German these counts are not a sample of a language — they describe the Qur'an exactly.

Three decisions worth knowing before you touch it

0. The tokenize pattern must cover the Qur'anic ANNOTATION block

[\u0620-\u065F\u066E-\u06D3\u06D5-\u06FF]+ — note that it runs to U+06FF, not U+06D3.

⚠️ Measured 2026-08-01: leaving out U+06D6–U+06ED cut words in half. هُدًۭى in al-Baqarah 2:2 carries U+06ED ARABIC SMALL LOW MEEM between the tanween and the alef maksura, so a class covering only letters and vowel marks tokenized it as هُدً + ى — two fragments, neither of them a word.

The corrected count over the full mushaf is 77,878 word tokens, down from 80,811, which is exactly what the pack build independently reports. Ranked-token coverage rose 86.0% → 89.7%.

⚠️ Several of those signs also stand ALONE between words, so split() now returns tokens made of no letters. They key to the empty string, and coverage() already excludes unkeyable tokens from its running count — but any caller doing its own arithmetic over split() must filter them, or every verse looks longer than it is.

1. normalize strips the vowel marks and nothing else

["stripArabicDiacritics", "stripTatweel"], deliberately short.

⚠️ normalizeArabicAlef IS NOT IN THE CHAIN, and adding it makes the pack worse. Measured 2026-08-01 over all 80,811 running tokens of the mushaf: folding أ إ آ ٱ together took ranked-token coverage from 68.5% down to 68.3%, because it also merges أن into ان and إن into ان — distinct words that the frequency list holds separately. The provenance file in luraty-language-packs warns about the same class of damage from the other direction: an unconditional final ى→ي turns على into علي.

It IS in compare, and that is not a contradiction. Normalising decides which word this is, where merging two words is a bug; comparing decides whether the learner's answer is right, where being forgiving about an alef someone typed differently is correct.

2. The mushaf spellings are DATA, not code

The 2,689 Uthmani forms that differ from their modern spelling — ٱلله for الله, فى for في, ءامنوا for آمنوا — are appended to lemmas.tsv as ordinary surface→lemma rows, inverted from the uthmani.tsv the pack build produces.

⚠️ This is what makes the pack usable on real mushaf text, and it is worth 17 points. Measured 2026-08-01: ranked-token coverage over the whole Qur'an went from 68.5% to 86.0% when those rows were added — and to 89.7% once the tokenizer stopped splitting words at recitation marks. The alternative was a new conditional normalize step in the engine — more code, in the one package that is supposed to know no language.

3. Verse text is NOT in this package

A pack is a dictionary; the Qur'an is content. The text lives in public.passages, loaded by tools/quran/. Keeping them apart is what lets a second Arabic pack (MSA) score the same verses, and what stops 340 KB of scripture shipping inside a lexicon.

Provenance

Built from luraty-language-packs, branch project-next-steps, languages/ar-x-quran/out/: Wikidata Lexemes (CC0) for lemmatisation, counts from the full mushaf (6,348 stored verses, 77,878 word tokens, 14,811 distinct surface forms). The Qur'anic text itself is public domain.

⚠️ That branch is not merged. Regenerating this pack means going and getting it.

Known residue

10% of running tokens still key to something outside the frequency list — رضا, زال, لئك, نهى and similar. These are lemmatiser artefacts: the CC0 lexicon resolves a form to a base the Qur'anic count never saw. They read as unknown words to every learner, which makes every text look slightly harder than it is. Fixing it is a pack-build problem, not a Luraty one.