Skip to content
All posts

8 min readCase study, Data visualization, Content design

Building Lexodus: an animated atlas of where words wandered

How we turned etymology into typed data with a grade on every hop, kept the popular myths separate from the evidence, and animated 848 journeys across one shared map projection.


Etymology has a folklore problem: a good story travels faster than the evidence. Everyone has heard that poshstands for “port out, starboard home” or that sincerecomes from sculptors working “without wax.” Neither holds up. Meanwhile the true stories are better and stranger: sugar starts as Sanskrit śarkarā, “grit, gravel,” and reaches English by way of Persian, Arabic, Medieval Latin and French. A dictionary entry flattens that into one line of abbreviations. We wanted to watch it move.

Lexodus is the result: search a word and an animated map traces it hop by hop, from the oldest form we can name to English, with every hop graded by how sure scholarship actually is. A second set of journeys runs the other way, into the Hebrew spoken in Israel. It is a self-initiated studio project, and the interesting engineering was never the animation. It was making honesty a property of the data.

Words
848
Graded hops
8,817
Languages reached
222
Myths labelled
83

A journey is typed data

Every word is a TypeScript object. Its main line is an ordered list of attested forms, oldest first, each one carrying a language id, the form in its native script, a romanization when that script isn't Latin, a short gloss, and the approximate year it is first attested. Every step after the first also records how the word arrived — inherited, borrowed, learned from texts, calqued piece by piece, or an eponym — and how confident we are in that link.

The main line stops at English. But words keep going, so side journeys hang off it as branches: Russian took sugar from Greek, Hindi kept the Sanskrit line. A branch names the language it sets out from, and it can fork from an earlier branch rather than the spine, so tea can take both of its historical roads — overland as chá, by sea as tê. When a language appears twice on a route, a branch can pin the exact form it leaves from: Brazilian tchau departs from Italian ciao, not from the older Italian word it grew out of. Across the corpus that adds up to 5,459 branches and 9,665 dots on the map, reaching 222 distinct languages; tea alone touches 29.

The language registry pins each language to one representative cultural center for the period it was in use — Jerusalem for Biblical Hebrew, Alexandria for Koine Greek, Vilnius for Yiddish — rather than drawing borders nobody could defend. That choice keeps the map honest about what it is: a picture of contact, not of territory.

Grading the link, not the word

The rubric has four grades, and the crucial decision was what they attach to. A grade describes the link into a step — did the word really pass from the previous language into this one — not the spelling and not the word as a whole:

  • Certain: standard references agree.
  • Probable: the mainstream view, but an intermediate stage or route is inferred.
  • Possible:a serious scholarly proposal that isn't consensus.
  • Disputed: a popular claim that specialists reject or consider unproven.

A word's overall grade is then its weakest link on the road to English: a journey is only as trustworthy as its shakiest hop. Sugar is a good example. The Arabic, French and English links are certain, but the exact route from India into Middle Persian is inferred, so the whole journey reads as probable. Of the 848 words, 495 grade certain, 279 probable, 66 possible and 8 disputed. The grade is visible on the map itself: certain hops draw as solid lines, and each weaker grade draws a sparser dash, so you can see which part of a route is a guess without opening a panel.

The data model also writes down rules a schema can't express on its own. Never invent an attested form; a reconstructed stage gets a leading asterisk and a note saying so. Round dates honestly. And years along a route never go backwards.

Myths live beside the evidence, not inside it

The tempting design is to treat a myth as a low confidence score. We kept them separate, because they answer different questions. The grade says how solid the real journey is; the myth field holds the story people tell instead, with the reason it fails. On the page it renders as its own labelled note, and the word is tagged into a browsable “Myths & disputes” category.

That separation matters because the two vary independently. The real route of guruis certain, yet the popular “dispeller of darkness” breakdown is a late devotional wordplay, so the word is both certain and myth-tagged. Coffee is probable, with the Kaffa-region story flagged as unproven. Posh is only possible, and its acronym story is flagged as first attested decades after the fact. And for a handful of words, such as kibosh and abracadabra, the journey itself is disputed. 83 words carry a myth; collapsing that into one score would have thrown away exactly the information readers come for.

The site's method page states the boundaries outright: no language is the mother of all the others, and each journey starts at the oldest form we can name, which isn't the same as a word's true beginning. As the corpus grew, Hebrew went from the whole premise to one origin among many — 146 of the 848 words today — and the site was renamed from “where Hebrew words wandered” to “where words wandered.”

One projection, many cameras

Every layer of the map projects through a single d3-geo Natural Earth projection fitted to a fixed 1000×520 world. A build script renders Natural Earth 1:50m coastlines, the graticule and the sphere through that same projection into one static SVG, and pages reference its pieces with <use href>, so the browser downloads and caches the geometry once no matter how many words you open. Language dots go through the identical function at runtime, which means a dot can never drift off its coastline.

Playback is ordinary state over time. Each word is flattened into an ordered list of hops, sorted by the year each form landed, with the main line winning ties so the spine reads first. One rule needed care: a branch hop may never play before the word has reached the place it departs from. Before each journey starts, a camera fits the bounding box of every stop and glides there from wherever the previous word left it. Hops draw as quadratic arcs bowed to the north, split at the current progress so the line grows toward its destination; a hop within the same city (Old French to French) becomes a small loop instead. Labels are placed greedily — current stop first, then the origin, then newest — trying four positions each and skipping any that would collide.

Two smaller decisions did a lot for readability. Hops are spaced evenly on the timeline, so a short modern journey isn't crushed against two millennia of Latin; the tick labels carry the real years and the page says so. And visitors who ask for reduced motion skip the animation entirely and get the finished map.

Zooming out: every living language

A companion page, /languages, applies the same map to a much larger question. It plots all 6,949 living languages listed in Glottolog 5.3, one dot each at Glottolog's coordinates, with extinct languages left out. A pinned build script regenerates the data from that release, so the numbers can be traced back to a fixed source.

Dots are timed by dated, graded expansion waypoints for the 21 largest or best-studied language families: a language appears when the nearest wave of its own branch reaches that point. The page states plainly that this models the family, not the moment that one language arose. Smaller families and isolates appear from the start. The page offers two views: one follows the Torah's account, dated by the Seder Olam chronology, and one follows historical linguistics. Two timelines run alongside, 9 entries from Torah tradition and 21 historical ones, each with its source. The historical entries use the same four confidence grades as the word atlas. The page deliberately keeps the two timelines separate rather than merging them.

Testing a dataset like code

With 848 hand-researched entries, the risk isn't a crash; it's a quietly wrong word. So the content has a gate, run alongside typechecking, lint, tests and the build. The validator checks every entry, including every branch:

  • Every language id exists in the registry, and every form, gloss and year is present.
  • Years never decrease along a route, and a branch can't start before the step it departs from.
  • The first step has no link type or grade; every later step must have both.
  • Any form not in Latin script needs a transliteration.
  • The main line ends in English, or in Modern Hebrew for the Into Hebrew words.
  • A word's overall grade is never stronger than its weakest main-line link, and anything with a myth is tagged as one.
  • Every word lists its sources.

On the current dataset it reports 848 words, zero errors and zero warnings. Alongside it, a Vitest suite of 18 tests pins the playback rules — including a check that runs every word in the corpus and asserts no hop ever plays before its departure point is reached.

The process note we'd stress most is the fact-check pass. After the corpus grew past 500 words, every entry from that round was re-verified against pages actually opened. About 80 dates were corrected along the way (guru moved from 1613 to 1806, boss from 1822 to 1645), mumbo jumbowas downgraded to possible, source lists were trimmed to pages genuinely consulted, and any year that couldn't be confirmed is now marked as approximate in its note.

What we'd tell a client

  • If trust is the product, put uncertainty in the schema. A field that must be filled is harder to fudge than a disclaimer at the bottom of the page.
  • Grade the smallest unit you can defend, then derive the summary from it. Weakest-link rollups are simple, explainable, and hard to game.
  • Keep the misconception and the evidence in separate fields. They answer different questions, and readers want both.
  • Treat editorial content like code: a validator in the check pipeline catches the mistakes reviewers stop seeing after the hundredth entry.
  • Pick one projection, or one source of truth for any shared geometry, and route everything through it.
The animation is what people share, but the product is a four-word rubric applied 8,817 times — and a validator that won't let a good story outrank the evidence.