ghunna
Tajweed rules, derived.
A derivation engine for classical tajweed. Vocalized Uthmani text in, rule annotations out: every span carries its trigger letters, a derivation in English and Arabic, and a citation to the line of the source poem it comes from.
What a call returns
import { annotateVerse } from "ghunna";
const { text, annotations } = annotateVerse(2, 255);
// each annotation:
// {
// rule: "iqlab",
// name: { arabic: "الإقلاب", transliteration: "iqlāb", english: "conversion to mīm" },
// range: [17, 22], // codepoint range into text
// derivation: "nūn sākinah/tanwīn followed by ب → the nūn is converted to a concealed mīm with ghunnah",
// citation: { text: "tuhfah", lines: [13] }, // line 13 of Tuḥfat al-Aṭfāl
// waqfDependent: false,
// confidence: "certain",
// }
The scope is riwāyat Ḥafṣ ʿan ʿĀṣim by ṭarīq al-Shāṭibiyyah. The library is pure TypeScript, runs identically in the browser and in Node, and ships as ESM and CJS.
Derived, not looked up
Existing digital tajweed resources are, without exception we are aware of, encodings of an already-annotated muṣḥaf: a fixed table of colored spans transcribed from a printed page. This library takes the opposite approach. It implements the rules as stated in the two canonical teaching poems, Tuḥfat al-Aṭfāl and al-Muqaddimah al-Jazariyyah, and derives every annotation from the letters and diacritics of the text alone.
The distinction has a precise technical form. The Uthmani encoding carries pronunciation hints printed in the muṣḥaf: the small mīm at iqlāb sites, the maddah sign over long madds. The engine never reads them. They are reserved for verification, where the derived output is compared against what the muṣḥaf tradition prints. A derivation engine can be checked against the printed tradition; a transcription of the printed tradition cannot be checked against anything.
Three consequences follow. First, every annotation can explain itself: the output carries the derivation and the citation, not just a color class. Second, recitation context becomes a parameter rather than a baked-in assumption; see the waqf model. Third, rule families that the digital datasets never carried at all, such as the tafkhīm and tarqīq family, can be derived like any other; see the rule catalog.
Verified against the printed tradition
The engine's output over all 6,236 verses is compared against two independent datasets and, at every disputed site, against page photographs of the printed Dar al-Maarifah tajweed muṣḥaf itself. Agreement over the mapped categories is 99.80% in continuation mode and 99.82% in stop mode. The 108 sites of disagreement are not averaged away: each one is classified, researched against the published tajweed literature, and documented in the residue. In every group the evidence favors the rules as written over the datasets, and 90 of the 108 reduce to a single identifiable defect in the reference dataset's madd classifier.
Install
npm install ghunna
// full package (bundled Qur'an text):
import { annotateVerse, getVerseText } from "ghunna";
// corpus-free core: bring your own Tanzil-Uthmani-encoded text
import { annotate, tokenize, RULE_META } from "ghunna/core";