indickit, live: text utilities for 22 Indian languages

Nine small utilities, in TypeScript and Go, for text in the 22 languages of India's Eighth Schedule: Hindi, Bengali, Tamil, Telugu, Marathi, Urdu, Gujarati, Kannada, Malayalam, Odia, Punjabi and the rest. Each one fixes one place where ordinary string code goes wrong on Indian text: Unicode normalization, search folding, stemming, letter (grapheme) segmentation, phonetic name matching and name search, transliteration to and from Latin letters, and a check that a word can be drawn whole (wellformed, not shown here; search-key joins normalize, stem and fold in one call). Every result on this page is computed in your browser by indickit 0.14.0, with examples from real government press releases.

Each package alone

normalize One encoding for text that looks the same

normalize(text, lang)

Gives text that looks the same one encoding, so equal text has equal bytes. It never changes a letter a reader can see.

Press offices type ড়, য়, ज़ and ਸ਼ as one code point or as two, and Malayalam chillu letters in an old way. To a computer, the two forms are different words.

The live demo needs JavaScript.

In the 50 releases (rules 2026-10-12): Bengali 51 of 51, Manipuri 50 of 50, Punjabi 48 of 50 documents change; Marathi 0 of 50. Held out: 88.1% of look-alike groups made byte-equal, 0 words changed in look (docs/normalize.md). New in 0.12.0: every font indickit holds decides what looks the same, and three faults are fixed (khanda ta, old Malayalam chillus before a vowel sign, a ZWJ inside a Malayalam letter).

22 languages

One name, typed in Latin letters, through every package in every language: deromanize writes it in the language's script, segment counts its letters, phonetic checks that the written name still matches what was typed, and romanize writes it back in Latin letters. A red cross marks a step that broke the name: the native spelling, or the Latin one written back, no longer matches what was typed.

The 22 languages of the Eighth Schedule and what indickit does in each
Languagederomanize the namesegment lettersphonetic key, matchromanize backback = typed?stemphonetic-search
Assameseas · Bengali-Assamese✓✓
Bengalibn · Bengali-Assamese✓✓
Bodobrx · Devanagari✓✓
Dogridoi · Devanagari✓✓
Gujaratigu · Gujarati✓✓
Hindihi · Devanagari✓✓
Kannadakn · Kannada✓✓
Kashmiriks · Perso-Arabic✓✓
Konkanigom · Devanagari✓✓
Maithilimai · Devanagari✓✓
Malayalamml · Malayalam✓✓
Manipurimni · Meetei Mayek✓✓
Marathimr · Devanagari✓✓
Nepaline · Devanagari✓✓
Odiaor · Odia✓✓
Punjabipa · Gurmukhi✓✓
Sanskritsa · Devanagari✓✓
Santalisat · Ol Chiki✓keys only
Sindhisd · Perso-Arabic✓✓
Tamilta · Tamil✓✓
Telugute · Telugu✓✓
Urduur · Perso-Arabic✓✓

Where it fails

How this was measured: the 50 releases are a held-out slice of the August 2023 month of pib-parallel, chosen by a hash of the release ID before anyone read them. No indickit rule was chosen on this text. The counts on this page were fixed before the text was read; the text was read once on 2026-10-08 and counted again with 0.12.0 on 2026-10-13 (both reads logged; nothing was chosen on either). The language table's preset names were written ahead of time by deromanize and romanize, since their tables for 22 languages weigh about 60 MB. Everything else runs live in this page. Text: Press Information Bureau, Government of India.