Blog
Release · 14 November 2026 · 5 min read

Lekhani now types 12 languages, each under 1 MB, in your browser

Type Hindi, Bengali, Marathi, Tamil, Telugu, Urdu, Gujarati, Kannada, Malayalam, Punjabi, Odia or Assamese in English letters and Lekhani writes the script, on your own device. Ahead of IndicXlit's model in all 12.

Most people who write an Indian language on a phone or a laptop don't use its script keyboard. They type it in English letters: "kemon acho", "kem cho", "eppadi irukkeenga". Turning those letters into the language's own script is called transliteration, and the tools that do it well usually run on a server or carry word lists of hundreds of megabytes.

Lekhani started on 30 October with Hindi, from a 0.87 MB download that runs inside a web page. Telugu, Tamil and Kannada followed. Today it covers 12 languages: Hindi, Bengali, Marathi, Tamil, Telugu, Urdu, Gujarati, Kannada, Malayalam, Punjabi, Odia and Assamese. Each one is under 1 MB, and all of it runs on your own device, so nothing you type is sent anywhere.

What Lekhani does, in about a minute. Every word on screen in a language's own script is the page's own output, recorded on the page one language at a time, at real speed.

What you get

You typeLekhani writesLanguage
kemon achoকেমন আছোBengali
kasa ahesकसा आहेसMarathi
aap kaise hainآپ کیسے ہیںUrdu
kem choકેમ છોGujarati
mazha peyyunnuമഴ പെയ്യുന്നുMalayalam
sat sri akalਸਤ ਸ੍ਰੀ ਅਕਾਲPunjabi
kemiti achhaକେମିତି ଅଛOdia
kene asaকেনে আছাAssamese
eppadi irukkeengaஎப்படி இருக்கீங்கTamil
ela unnaruఎలా ఉన్నారుTelugu
hegiddiraಹೇಗಿದ್ದೀರಾKannada
aap kaise hoआप कैसे होHindi

All lowercase, typed the way people text. Each of these was typed on the page itself before this post went up.

How it works

Each language has its own small model, 0.8M or 1.2M parameters stored at 4 bits, plus a list of that language's common words. The model reads a word letter by letter and proposes its 8 best spellings; the list moves a common real word up when the model is unsure. A word that isn't in the list, such as a new name, still works from the model alone.

One runner, 15.8 KB of JavaScript (6.6 KB compressed) with no dependencies, serves all 12. Everything a page loads for one language (the model, its word list, two small settings files and the runner) is between 0.71 and 1.0 MB.

Use it in your own page

Download translit.js and the folder for your language from Hugging Face or GitHub, serve them next to your page (any static host works), and:

import { Transliterator } from "./translit.js";

const tr = await Transliterator.load({
  model: "tamil/model.q4.gz", json: "tamil/model.json.gz",
  words: "tamil/words.bin.gz", rerank: "tamil/rerank.json",
});

tr.text("eppadi irukkeenga");  // எப்படி இருக்கீங்க

tr.text() writes every run of English letters in the language's script and leaves everything else as it is. tr.word() returns the 8 spellings the model considered, best first, if you want to show suggestions as a keyboard does. The same runner works in Node 18 or newer; the README has both examples. Nothing is sent to a server.

The result

We scored every language on the Aksharantar test (AI4Bharat): every romanised word in the test, top-1 exact match against any reference spelling, the same words and the same scorer for every system. Each language's settings were chosen on the validation set and the test was scored once, between 28 October and 13 November 2026.

LanguageTest wordsLekhaniIndicXlit's modelGap (paired 95% interval)
Hindi9,99165.9%58.9%+7.0 (+6.1 to +8.0)
Tamil11,40574.2%64.2%+10.0 (+9.3 to +10.7)
Marathi12,05970.9%63.2%+7.8 (+7.0 to +8.6)
Bengali13,36770.2%55.4%+14.8 (+14.0 to +15.6)
Urdu14,61757.6%44.4%+13.2 (+12.4 to +14.0)
Kannada11,16579.4%72.7%+6.7 (+6.0 to +7.4)
Telugu9,93681.2%72.6%+8.5 (+7.7 to +9.3)
Malayalam12,34367.1%59.5%+7.6 (+6.9 to +8.4)
Gujarati17,40272.8%61.2%+11.6 (+10.9 to +12.3)
Punjabi10,94955.7%44.5%+11.2 (+10.3 to +12.0)
Odia4,20149.9%45.6%+4.2 (+3.0 to +5.5)
Assamese5,47658.6%53.1%+5.5 (+4.4 to +6.7)

IndicXlit's model on its own has 11.5M parameters, run with its default settings. It is the comparison we set for every language before training, and every paired interval above is clear of zero.

Where it falls short

  • IndicXlit's full Python package is level or ahead in ten of the twelve. It adds a word list of millions of words per language (358 MB in memory for Hindi). Lekhani is ahead of it only in Bengali (+2.8) and Urdu (+9.4), level in Tamil, Telugu, Gujarati and Punjabi, and behind in Hindi (-2.8), Marathi (-1.8), Kannada (-1.4), Malayalam (-2.1), Odia (-2.1) and Assamese (-1.8). If you can hold those lists in memory, the package is the more accurate choice.
  • Names are weak, except in Hindi. In the other eleven languages, the test's name rows get 25% to 60% right on the first guess.
  • Odia, Punjabi, Urdu and Assamese are weak in absolute terms: 50%, 56%, 58% and 59% of test words right on the first guess.
  • Odia and Assamese have no real-typing test. Their scores cover the test's dictionary-style romanisation, not words as people type them in chat.
  • One word at a time, no sentence context, and no native speaker has reviewed the misses yet; some may be accepted spellings that the answer lists don't include.

Try it

Code and weights are open under Apache-2.0. If you write one of these languages every day, tell us which words it gets wrong; they are what we want to fix next.

Thank you to AI4Bharat for Aksharantar, IndicXlit and IndicCorp, which this work stands on.