A bitext word-alignment and word-order illustrator for translators, language learners, conlangers, and linguists.
Live demo: https://word-order.mkpo.li/ Β· First published: August 2022
Paste sentences in any languages, click matching words across rows, and the tool draws curved connectors. Reordered translations, one-to-many mappings, and many-to-one mappings all stay readable.
- π€ Locale-aware tokenization β CJK, Thai, and other unspaced scripts are auto-segmented; use
|to fix the cases where the segmenter guesses wrong. - γ°οΈ Curved connectors with tunable curvature, line width, gap, and endpoint correction.
- π·οΈ Multi-tier annotations above and below each word β gloss, IPA, morphemes, as many tiers as you need.
- π Ruby annotations (
<ruby>ζΌ’<rt>γγ</rt></ruby>) render inline in source text and in any annotation tier. - βοΈ Per-token merge and split at any grapheme boundary.
- π² Scramble equivalency β one click reorders the color groups to show how much a translation reshuffles meaning.
- π€ BYO-key LLM translate-and-align β supply your own OpenAI, Anthropic, or Gemini key (stored only in localStorage). Translate into one or more targets at once with auto-glossing and auto-alignment; any BCP-47 code works as a target.
- π Examples gallery β SOV vs SVO, RTL scripts, Romance pro-drop, multi-script CJK, Turkish interlinear gloss, Ainu polysynthesis, Genesis 1:1 across Hebrew / Koine Greek / Latin / English, and more.
- πΎ localStorage autosave and export as SVG, PNG, PDF, or re-importable JSON.
- π UI in 30+ languages via Paraglide β including Ainu, Korean Hanja, Esperanto, Interlingua, and Toki Pona.
- Type or paste a sentence into the input box and press Add.
- (Optional) If you've added an API key in Settings, click Translate to pick target languages β the tool fills in translated rows, glosses, and tentative alignments for you.
- Click a word in one row, then a matching word in another, and press Confirm to connect them. Clicking an already-linked word lets you edit its color group.
- Use the pencil icon on any row to fine-tune tokenization or add annotation tiers above and below.
- Tweak spacing, curvature, fonts, and text alignment in the Options panel.
- Export from the Export menu β or load a ready-made example from Examples.
- SvelteKit (Svelte 4) + TypeScript
- Vite (Vite 5)
- Paraglide for i18n
dom-to-svganddom-to-imagefor vector and raster export@neodrag/sveltefor draggable dialogscolorjs.iofor OKLCH color palette generation- Iconify for icons
- Deployed on Vercel
Working draft β re-verify each tool's current feature set before citing the comparison externally; add any peers that are missing.
- Bitext Align (source) β SvelteKit. By Dani Polani under the tinygodsdev org. Multi-line editor with per-line LTR/RTL, gloss/IPA tiers, PNG/SVG/PDF/HTML export, URL-encoded share, light/dark theme, 3 built-in examples.
- BasicCAT Bitext Aligner β sentence/word aligner shipped inside a CAT translation suite.
- Academic prototypes (paper-only, not always hosted):
- Yawat β uses dynamic markup to keep the alignment view from getting visually busy as connections pile up.
- Line-a-line β drag-and-drop alignment for under-resourced parallel corpora.
- CLUE-Aligner β manual annotation of contiguous and non-contiguous multiword expressions.
- SWIFT Aligner β visualization + alignment + morpho-syntactic cross-language transfer in one GUI.
- LangMap (source) β 100 sentences Γ 223 languages of hand-aligned word-order data, plus a 957-language word atlas with IPA and a D3 family tree.
Interlinear gloss formatters (adjacent category β they typeset glosses, they don't align across rows)
- Leipzig.js (source) β JS library for embedding Leipzig-style glosses in HTML.
- Gloss My Gloss β browser tool that formats glosses into aligned columns with abbreviation tooltips.
- leipzig-glossing (Typst) β Typst package for typesetting glosses in documents.
- FieldWorks Language Explorer β SIL's desktop suite for full interlinear text annotation with a persistent lexicon.
Survey conducted May 2026 from each tool's then-current live build, GitHub repo, and README. Cells marked ? were not directly verifiable from the public surface and should be confirmed by the tool's author before being cited externally.
Click to expand the comparison tables
| Word Order Illustrator | Bitext Align | LangMap | |
|---|---|---|---|
| Category | Authoring | Authoring | Curated atlas |
| Web | word-order.mkpo.li | aligner.tinygods.dev | langmap.heuron.com |
| Repo | mkpoli/word-order | tinygodsdev/bitext-word-alignment | jounlai/langmap |
| Author | @mkpoli | Dani Polani / tinygodsdev | Jounlai Cho / Heuron Corp. |
| First public release | Aug 2022 | Apr 2026 | Mar 2026 |
| Repo created | 2022-08-23 | 2026-04-18 | 2026-03-12 |
| License | MIT | MIT | MIT (README only β no LICENSE file in repo) |
| GitHub stars (May 2026) | 13 | 1 | 5 |
| Tech stack | SvelteKit 2 Β· Svelte 4 Β· TS Β· Vite 5 Β· Vercel | SvelteKit Β· Vite 8 Β· Docker | Static HTML/JS Β· D3 Β· no build |
| Build step required | β Vite | β Vite | β static files |
| Feature | Word Order Illustrator | Bitext Align | LangMap |
|---|---|---|---|
| Manual click-to-link alignment | β | β | n/a (pre-aligned) |
| Curved BΓ©zier connectors | β tunable | β tunable | β |
| Connector parameters exposed | curvature, line width, gap, straight length, endpoint correction | style, colors, tokens, fonts | minimal |
Intl.Segmenter tokenization (CJK / Thai) |
β | β whitespace + manual join | n/a |
<ruby> (furigana / pinyin / zhuyin) |
β tokens & glosses | β | β |
| Interlinear gloss tier | β | β extra tier | β |
| Per-token merge / split dialog | β | partial | β |
| Per-line RTL / LTR toggle | implicit (BCP-47) | β explicit | β |
| Multiple sentences (> 2 rows) | β | β | β |
| Drag to reorder rows | β | β | β |
| Delete row | β | β | β |
| Reorder color groups | β | ? | n/a |
| Scramble equivalency view | β | β | β |
| LLM translate + auto-align (BYO key) | β | β | β |
| Feature | Word Order Illustrator | Bitext Align | LangMap |
|---|---|---|---|
| Built-in examples | 10+ | 3 | 100 sentences Γ 223 langs |
| UI languages | 32 | 1 (EN) | 21 |
| Light / dark theme | β | β | β |
| Font customization | β family / style / size | β Fonts panel | font size only |
| Color palette customization | β OKLCH auto + Settings | β Colors panel | β fixed |
| Language metadata (family / typology / IPA) | β | β | β extensive |
| Mobile responsive | ? | ? | β |
| Keyboard navigation | ? | ? | β arrow keys, random |
| Guided tour / Help | β | β | β |
| Feature | Word Order Illustrator | Bitext Align | LangMap |
|---|---|---|---|
| Autosave (localStorage) | β | ? | n/a |
| Multiple workspaces / tabs | β | β | n/a |
| URL share (state in hash) | β | β | β |
| Social share buttons | β | β | β X / Facebook / LINE |
| Export SVG | β vector | β vector | β |
| Export PNG | β (2Γ fixed) | β (2Γβ6Γ picker) | β |
| Export PDF | β | β | β |
| Export HTML | β | β | β |
| Export JSON (project archive) | β | β | β |
| Export CSV | β | β | β |
| SEO (OG image, JSON-LD) | β | β | β |
Bun is the recommended package manager (the lockfile is bun.lockb) and must be installed before running the development commands.
bun install
bun devOther scripts:
bun run build # production build (Vercel adapter)
bun run preview # preview the production build locally
bun run check # run paraglide compile, svelte-kit sync, and svelte-check
bun run lint # prettier --check + eslint
bun run format # prettier --write
bun run paraglide:compile # regenerate i18n message modules after editing project.inlang/messages/*.json
bun run test # Playwright E2E testsTranslations live in project.inlang/messages/*.json. To add a new locale:
- Add the locale code to
project.inlang/settings.json. - Copy
project.inlang/messages/en.jsontoproject.inlang/messages/<locale>.jsonand translate the values. - Run
bun run paraglide:compileto regenerate the typed message modules. - Add the locale to
src/lib/lang.tsif it needs a display name override.
Missing keys fall back to the base locale (English), so translations can be incremental.
β οΈ Never fill an unknown locale string with English or an AI-guessed translation. It is strictly better for a key to be absent from a locale file than for the value to be a guess: when absent, Paraglide falls back to English and the gap is visible; when "filled" with a bad translation, the gap is hidden and the UI silently misinforms users. If you don't have a verified translation from a speaker, leave the key out β especially for low-resource and endangered locales (ain,grc,la,ko-Kore,ja-Hira,tok).
Issues and pull requests are welcome β https://github.com/mkpoli/word-order/.
- Bug reports: include the live-demo URL with your
?state if you can reproduce there, plus browser + OS. Screenshots help when the issue is visual. - PRs: please run
bun run lint,bun run check, andbun run testbefore opening. If you touch user-visible strings, follow the Adding a new UI language instructions and runbun run paraglide:compile. - Commit style: this repo uses Conventional Commits (
feat:,fix:,docs:,chore:, etc.) β your PR's commits should follow suit. - New examples for the gallery are a great low-friction way to contribute: edit
src/lib/examples.ts.
Created by @mkpoli β Twitter Β· GitHub.
Source code is released under the MIT License Β© 2022β2026 mkpoli.
This application doesn't claim rights over the illustrations you create with it. How you use or share them is entirely up to you. Sharing the tool itself is appreciated.
