Lontara
A Bugis Lontara reader and writer that lists every possible reading when the script leaves the word open

- agreement with Bugis Wikipedia pairs, up from 56%
- 94%
- word-list entries, each with its source
- 1,323
- Lontara–Latin pairs written by Bugis users
- 97
- open questions recorded instead of guessed
- 7
On this page
The problem
Lontara is the script of the Bugis language of South Sulawesi. It has 23 consonants and five vowel signs, but no way to write a consonant on its own. So it never records consonants at the end of a syllable, doubled consonants, a nasal before a consonant, or the glottal stop. The words mata, matta and manta are all written the same way. A reader picks the word from context.
Existing converters hide this. They return one confident Latin spelling, which is a guess presented as an answer. A signmaker can put a misspelled name on a permanent sign. A learner can be taught a rule that doesn't exist. Someone reading family manuscripts gets one reading where six are valid, with no sign that a choice was made.
What I built
The tool lists every reading the script allows
Paste Lontara into the reader and it returns a tree of possible Latin readings. Each branch point is labelled with the kind of ambiguity that caused it: a final consonant, a doubled consonant, a nasal or a glottal stop. Each choice the tool makes must carry a reason, so it can't pick a reading silently. The writer goes the other way. It lays Latin onto a palm-leaf band and marks lost information on the stroke where it was dropped.
The spelling rules live where a reviewer can read them
The eleven spelling rules sit in a data file, each marked as cited, provisional or derived, with its citation. The code only interprets that file. A Bugis reader who doesn't program has to be able to audit the orthography, and one page in the app shows every rule with its source.
Readings come from a word list, never from a guessed rule
The obvious reader would try every consonant that could close each syllable. That needs a list of Bugis final consonants, and I couldn't find one to cite. Guessing it would produce confident readings that aren't Bugis. So a reading counts only if it is a known word that the writer turns back into exactly the same Lontara. The cost is that results are only as complete as the word list, and every result says so.
Real Bugis writing caught a 56% error rate
Bugis Wikipedia has pairs of Lontara and Latin written by people who use the script. I extracted 97 of them and scored my rules against them. They agreed 56% of the time. The test found three mistakes. Two vowel letters were the reverse of what their Unicode names suggested, é was missing entirely, and people write the glottal stop as q. Fixing them raised agreement to 94%. Two other oddities, with two cases each, may be errors in the articles, so I left them for a reviewer.
The word list claims only what it can support
The word list has 1,323 entries, and each one records where it came from. 85% of the source dump turned out to be bot-generated stubs, so the list makes no claim about how common a word is, and the build fails if an entry does. Some entries are Indonesian, English or Vietnamese place names the tool can't tell apart from Bugis, so the reader badges those readings and ranks them low.
Result
Lontara is live and public, in Indonesian and English, and works offline after the first visit. It includes an on-screen Lontara keyboard, because most phones have none. By its own rules it is deployed but not launched. No Bugis reviewer has signed off yet, the code enforces that gate, and every page says so. The spelling page lists seven open questions I recorded instead of guessing. It says plainly that it is a personal project, not an authority, and can be wrong. It transliterates and never translates. I built it alone in six days, from late July to early August 2026.
Under the hoodTechnical detail for engineers
- Characters come from the Unicode Buginese block (U+1A00–U+1A1F), which has no virama. Latin e is U+1A1B and é is U+1A19, the reverse of what the character names imply.
- Rules live in
data/rules/rules.json: rule set v0.2.0, 11 rules across 4 stages (5cited, 2provisional, 4derived).pnpm rules:reportprints them;/ejaanrenders them. - The engine is pure:
(input, direction, options, ruleSet, lexicon) => TransliterationTrace, enforced by an ESLint override andtests/invariants.test.ts.interpret.tswrites;enumerate.tsreads by inverting the writer over the lexicon. - An ambiguity is
{ class, candidates, chosen, reason, spans }withreasonrequired. Classes are the closed setfinal,gemination,prenasal,glottal. - Trace steps carry input and output spans and name which cluster array they index. Mixing the two once pointed connector strokes at the wrong glyph.
- NFC normalisation and
Intl.Segmenterfor grapheme clusters; neverstr[i]or.split('')for glyph logic. - The corpus comes from
{{multiscript|…}}templates in the Bugis Wikipedia dump (CC BY-SA 4.0).tests/corpus.test.tspins the 94% rate and requires every remaining disagreement to be explained. The unacted findings arengp→ MPA andnc→ NYCA. - All 1,323 lexicon entries are
attestation: "corpus"andband: "unknown". Before de-botting, nine "common" words appeared in 617–620 articles each because they were the colour key of one repeated map caption. data/rules/reviewers.jsonis empty andpnpm gate:checkexits 1; CI runs it withcontinue-on-errorso the writer and conformance page still build.- CI enforces a 200 KB gzipped JS budget and checks the build-time service worker's precache list against the files on disk, then fetches every URL. The worker omits
skipWaitingandclients.claimto avoid mixing builds mid-session. - Shared text lives after the
#in the URL, so it never reaches a server log. - Four runtime dependencies: Next.js 14.2.15, React 18.3.1, React DOM and Zod 3.23.8. No transliteration library. Fonts (Noto Sans Buginese, Gentium Plus, Space Mono) are subset to 76 KB of woff2.
- 281 tests in 6 files; 6 routes in two locales, including the full script reference at
/aksara; 12 hard rendering strings on the conformance page. - The first spec covered Javanese and Balinese too. I cut it to Bugis because Noto Sans Buginese has 41 glyphs and 2 OpenType features. Nulisa is linked for the other scripts. Urupu, the endonym, is the fallback name.
- About 9,300 source lines and 35 commits from 30 July to 4 August 2026, across three active days.
Screenshots
Hiring, or building something similar?
I'm open to full-time roles and select freelance work.