Ship your React app in every language

Wrap JSX in <T>, run one command, commit the JSON. An LLM translates every string with the context of your code.

No manual keys, no locale files to maintain by hand, no runtime fetches. 10,000 words a month free.

app.tsx
<T>  Welcome back, <Var name="user">{user.name}</Var>!  You have <Plural n={keys} one="one API key"    other="several API keys" />.</T>
terminal
$ npx foony-translate translateUploaded: 12 new, 202 already translated or queuedWrote src/translations/fr.json (214/214 entries)Wrote src/translations/de.json (214/214 entries)

The runtime, running

This is not a screenshot. The paragraph below renders through the real @foony/translate runtime with real locale JSON from this repo.

Live demo

You are reading output from the @foony/translate runtime, running in your browser right now. Switch the locale above and this exact JSX re-renders from a different JSON file.

Maya pushed 3 new strings today, so the next CLI run translates just those 3. Everything unchanged is already hashed and stays free.

New strings
3
Plural forms come from CLDR rules for the active locale.

English is the source locale: the JSX above renders as written, no lookup involved.

Wrap, translate, commit

Identity is a content hash of the source, so identical strings share one translation and nothing needs a manual key.

  1. Wrap

    Put <T> around static JSX. Dynamic values go in <Var>, <Num>, or <DateTime> and never leave your app. Conditional copy goes in <Branch> or <Plural> so every variant gets translated.

  2. Translate

    The CLI parses your source with a real AST, hashes every entry, and uploads only what changed. An LLM worker translates each string with your context notes, then the CLI writes per-locale JSON.

  3. Commit

    The JSON files live in your repo like any other code. The runtime holds no locale state and fetches nothing, so translated builds are as static as English ones.

You stay in charge of the words

Machine translation gets you to every locale. The dashboard and CLI keep the result reviewable, fixable, and enforceable in CI.

Review and edit
Browse every entry, fix a translation by hand, and it stays fixed: human edits survive future runs unless you revert them.
Retranslate on demand
Queue a single locale or a whole entry again. Failed rows always requeue.
Gate CI offline
foony-translate check verifies every entry has a translation in every locale, with no network and no key.
Meter what matters
Billing counts source words per entry and target locale. Re-running the CLI on unchanged content costs nothing.

Your app already knows English

Teach it the rest this afternoon. The free plan covers 10,000 words a month, enough for most side projects end to end.