Geni / Translation Exchange · 2009 – 2018
Translation Markup Language — expressing meaning, not strings
A language and runtime for representing dynamic product language as composable semantics—tokens, pluralization, gender, cases, decoration, and word order—across frameworks and human languages.
Role: Creator & Principal Architect
- Language infrastructure
- DSLs & runtimes
- Localization
Origin
The story
TML began inside Geni’s Newsfeed. An activity story looked like a sentence, but it was really a structured object: an actor performed an action on a target, names linked to profiles, counts selected plural forms, gender changed verbs, permissions affected visibility, and each language wanted to arrange those pieces differently.
Conventional resource bundles reduced that object to an interpolated string. The source language’s grammar leaked into every translation, formatting became fragile, and developers accumulated one-off keys for combinations that should have been rules.
I designed Translation Markup Language as a small semantic layer between application data and rendered language. Templates identified meaningful tokens and their dependencies; language engines evaluated numeric, gender, list, and case rules; decorators preserved links and presentation without making markup part of the translation.
The same model grew from Geni into the open-source tr8n framework, proved itself at Yammer and Kongregate, and became the runtime foundation of Translation Exchange. What started as a way to translate complex social stories became a cross-platform language system.
The accompanying slides come from my TML and Universal Translation Memory presentation. They capture the mature design: a consistent SDK model, contextual grammar, application-controlled delivery, and a graph of reusable translation knowledge.
Collaboration
People I built this with
The people behind this chapter—and the part each of them played in shaping the work.
CTO & Co-Founder, Triangle Health · Former CTO, Bird and Geni
Justin and I built tr8n together at Geni, turning TML from a language model for complex Newsfeed stories into production localization infrastructure. Our work connected semantic templates, language rules, community translation, and the application runtime.
Co-Founder & Product Lead, Translation Exchange · Former Director of Product Development, Geni
Ian helped turn TML’s deeply technical language model into translator and product experiences people could understand. Our collaboration connected semantic localization infrastructure to in-context workflows and a coherent cross-platform product.
Journey
Inside the language
The file handoff was the first bottleneck
The standard localization loop extracted content into resource files, uploaded those files to a translation system or provider, waited, downloaded translated files, merged them back into the application, and repeated the process for every change.
That workflow treated localization as a release phase rather than a continuous part of product development. It duplicated state, created synchronization problems, and inserted miniature waterfalls into otherwise agile teams.
Four principles shaped the solution
The design centered on consistency, adaptability, contextualization, and agility. Developers needed one understandable model across frameworks; language behavior had to remain extensible; translators needed to work inside the real product context; and localization could not block the development cycle.
Those principles pushed TML beyond a syntax. It became a contract connecting application code, language rules, translation tooling, and runtime delivery.
One semantic model across runtimes
TML kept the host language idiomatic while preserving the same conceptual operation: translate a label, provide its meaning, and bind structured tokens. Ruby, PHP, Java, Objective-C, JavaScript, Python, and other environments could expose native APIs without inventing a new localization model.
The consistent surface made translations portable across applications and let SDKs share token semantics, context rules, and fallback behavior even when their implementations were different.
- Native APIs for each host language
- Common template and token semantics
- Framework-independent context rules
- Shared translation identity
- Consistent fallback behavior
- Portable language configuration
Tokens turned sentences into composable structure
Data tokens represented values such as a person or count. Decoration tokens represented links, bold text, and native presentation. Tokens could nest, refer to objects rather than preformatted strings, and carry context such as gender or number.
This separation let translators rearrange meaningful units while applications retained control of URLs, objects, and rendering. A single template could combine a linked user, a pluralized distance, a possessive pronoun, and visual emphasis without embedding brittle HTML in the translated sentence.
- Data tokens and object bindings
- Decoration tokens for links and formatting
- Nested token composition
- Named semantic roles
- Language-controlled word order
- Host-controlled rendering
Grammar became data-driven context
TML attached grammatical dependencies to tokens instead of scattering conditional branches through application code. Numeric rules selected plural categories; object metadata selected gender forms; language cases transformed names and dates; list rules and ordinals followed the target language.
Each language supplied its own rule definitions. The runtime evaluated those rules against token values and selected the matching translation variation, allowing the same source intent to produce structurally different results.
- CLDR-informed numeric categories
- Gender-dependent verbs and pronouns
- Possessive, dative, genitive, and other cases
- Ordinals, dates, and lists
- Multiple context dimensions in one template
- Language-specific rule configuration
The SDK kept delivery close to the application
The runtime lived with the application rather than inside a rendering proxy. SDKs discovered and synchronized templates with the translation service, approved releases moved through a global CDN, and applications maintained local caches for fast, resilient rendering.
That architecture preserved SEO, avoided client-side flicker, kept content under developer control, and allowed translations to update without requiring every application process to depend directly on the translation service.
Universal Translation Memory treated language as a graph
TML templates gave translations more structure than a source-and-target string pair. Universal Translation Memory extended that idea into a shared graph where a translation key could connect to many language options, context rules, project uses, votes, and quality signals.
Translation and translator rankings helped useful work rise through community input, while applications could lock approved variants for their own context. The long-term goal was a reusable language knowledge layer: translate a compatible concept once, improve it collectively, and apply it across products without erasing provenance or control.
Context
The problem and my role
Problem
Traditional localization systems flatten application language into keys and strings. That works for static labels, but breaks down when a sentence contains people, links, counts, gender, grammatical cases, nested formatting, and language-specific word order. File handoffs compound the problem by disconnecting translation from the continuously changing application.
Role
Designed TML at Geni to localize structured Newsfeed stories, then evolved its parser, token model, context rules, language cases, SDK conventions, caching strategy, and shared translation memory through tr8n and Translation Exchange. I also presented the architecture and developer model to the internationalization community.
Constraints
- Represent grammar without forcing every language into the shape of the English source sentence
- Keep one recognizable authoring model across Ruby, PHP, Java, JavaScript, Objective-C, and other runtimes
- Compose data, formatting, links, plurals, gender, and grammatical cases without exposing application code to translators
- Support languages with very different plural categories, gender rules, cases, and word order
- Keep localization in the development flow instead of relying on repeated extraction, upload, download, and merge cycles
- Serve translations from the application’s own infrastructure with local caches and resilient fallbacks
- Reuse compatible translations without losing project context, provenance, quality, or control
System
Architecture
System map
From semantic template to localized sentence
The runtime combined application-owned data with target-language rules and translator-authored variations before handing safe structure back to the host renderer.
- 01
TML template
Declares source intent, descriptions, data tokens, decorators, and grammatical dependencies.
- 02
Token binding
Binds values and domain objects such as users, counts, dates, links, and lists.
- 03
Context evaluation
Derives numeric, gender, list, and other contextual categories from token values.
- 04
Language rules
Select matching translation variations and apply cases, ordinals, date forms, and word order.
- 05
Decoration
Reconstructs links, nested formatting, or native UI attributes without putting unsafe markup in translations.
- 06
Localized output
Returns a natural sentence rendered by the application in its own environment.
System map
From translation work to application delivery
SDKs synchronized structured templates with translation workflows while CDN releases and local caches kept runtime delivery fast and resilient.
- 01
Application SDK
Discovers templates, preserves context, renders fallbacks, and records usage.
- 02
Translation service
Supports in-context translation, rule-aware editing, voting, review, and approval.
- 03
Release
Packages approved translations and language configuration into versioned artifacts.
- 04
Global CDN
Distributes translation releases without coupling application requests to the management service.
- 05
Local cache
Static or dynamic caches keep rendering fast and available inside the application.
- 06
Runtime
Resolves templates and evaluates context using local application data.
Execution
What I built
- Designed a compact template language for data tokens, decoration tokens, nested structure, descriptions, and source grouping.
- Built context evaluation for pluralization, gender, numeric categories, ordinals, dates, lists, and language cases.
- Separated semantic translation structure from host-language rendering so links, formatting, and native UI decoration remained safe and composable.
- Created language configuration and rule engines that could express different grammatical systems without hard-coding every language into application logic.
- Implemented parsers, runtime evaluators, caches, fallbacks, translation lookup, and synchronization in the tr8n framework and cross-platform SDKs.
- Connected application SDKs to translation management, CDN releases, static or dynamic local caches, and in-context translator workflows.
- Designed Universal Translation Memory around unique translation keys, contextual variants, reuse across projects, voting, ranking, and provenance.
- Validated the model in complex social products and then documented, open-sourced, presented, and productized it for broader adoption.
Tradeoffs
Technical decisions
Model semantic templates instead of opaque keys
- Decision
- Represent tokens, roles, dependencies, and decorations explicitly in the translation unit.
- Why
- Dynamic product language needs enough structure for translators and runtimes to change grammar and word order safely.
- Tradeoff
- The model required custom parsing, storage, debugging, migration, and translation tooling beyond conventional resource bundles.
Attach context to token values
- Decision
- Derive plural, gender, case, and other rule categories from bound objects and values at runtime.
- Why
- Grammar depends on what a sentence is saying, not only on which static key the developer selected.
- Tradeoff
- Runtime context is more expressive but requires stable object adapters, deterministic rule evaluation, and careful fallback behavior.
Separate decoration from translation
- Decision
- Let translators place named decoration tokens while the host application owns their concrete HTML or native rendering.
- Why
- Translators need control over sentence structure, but URLs, components, attributes, and styling should remain safe application concerns.
- Tradeoff
- Nested token parsing and renderer implementations become more complex than interpolating a plain string.
Use shared abstractions with language-specific rules
- Decision
- Define common context interfaces while allowing every language to provide its own categories, cases, and transformations.
- Why
- A universal runtime should share machinery without pretending all languages have the same grammar.
- Tradeoff
- Language configuration becomes a maintained product surface that needs linguistic expertise and extensive examples.
Render through SDKs and local caches
- Decision
- Keep translation evaluation in the application, with management and CDN systems supplying versioned language data.
- Why
- Application-owned rendering protects performance, SEO, availability, and native integration while allowing independent translation releases.
- Tradeoff
- Cross-platform SDKs and multiple cache strategies create substantial compatibility, release, and support obligations.
Make translation knowledge reusable
- Decision
- Model a translation key and its contextual variants as shared graph nodes with project usage and quality signals.
- Why
- Common software concepts should improve through reuse instead of being translated independently in every product.
- Tradeoff
- Reuse requires strict rules for compatibility, privacy, provenance, ranking, project overrides, and trust.
Value
Product impact
User impact
Let developers author dynamic product language without enumerating every grammatical combination, while translators could produce natural results in context and retain control over target-language structure.
Business impact
Turned a difficult internal localization problem into reusable infrastructure, an open-source framework, a cross-platform SDK model, and the technical foundation for Translation Exchange.
Results
Outcomes
- Localized dynamic Newsfeed stories that combined actors, targets, links, objects, gender, plurals, permissions, and language-specific word order.
- Created a consistent semantic model that could be implemented across server, web, mobile, and native SDKs.
- Reduced one-off translation keys and application conditionals by moving grammatical variation into explicit language rules.
- Enabled translators to rearrange meaningful tokens and work in context without editing application code or embedded markup.
- Provided the runtime foundation for Geni’s community localization, Yammer’s rapid translation into more than twenty languages, and the Translation Exchange platform.
- Open-sourced a body of language infrastructure that still documents an alternative to static key-value localization.
- Anticipated a broader idea now central to language-aware software: meaning is structured, contextual, and reusable.
Reflection
Lessons learned
- “Language cannot be modeled faithfully as a bag of strings; meaning lives in roles, relationships, context, and structure.”
- “A universal abstraction should standardize the contract while leaving room for languages to remain genuinely different.”
- “Developer ergonomics, translator ergonomics, and runtime correctness are one system—optimizing only one moves complexity onto the others.”
- “Separating semantics from decoration makes translations both more expressive and safer to render.”
- “Continuous localization requires delivery architecture as much as translation tooling.”
- “Reusable language knowledge is powerful only when provenance, context, privacy, and project control remain explicit.”
Tools
Stack
Next case study
Geni — one shared family tree for humanity →





