wuchale (pronounced "wuh-cha-lay") is a compile-time internationalization
toolkit that requires no code changes. Write your components naturally, and
wuchale automatically extracts and replaces translatable messages at build
time.
- 🧼 No extra syntax! - Your normal code is enough, your codebase stays clean
- 📦 Tiny catalogs to bundle - Text catalogs are just arrays, no keys necessary, like Protobuf
- 🔌 Zero-effort integration - Add i18n to existing projects without rewriting code
- 🧩 Framework agnostic - Works with React, Preact, Svelte(Kit), SolidJS, Astro, and plain JS/TS
- ✨ Optional AI translation - Configurable integration for automatic on-the-fly translations
- ⚡ Full, granular HMR support - Live updates during development, including AI auto-translation
- 📦 Tiny footprint - Very few (less than 5) additional dependencies, no bloated
node_modules - 🧠 Smart extraction - Uses AST analysis to handle nested markup, conditionals, loops, and complex interpolations
- 🌍 Standard .po files - Compatible with existing translation tools and workflows
With traditional i18n:
<p>{t('Hello')}</p>
<p><Trans>Welcome {userName}</Trans></p>With wuchale:
<p>Hello</p>
<p>Welcome {userName}</p>No imports, no wrappers, no annotations. wuchale handles everything at
compile time by analyzing your code and automatically extracting translatable
strings.
See the Getting Started guide for instructions specific to your project type.
- Scans your source code using AST and identify translatable text content
- Extracts strings into standard
.potranslation files for translators - Compiles catalogs into compact modules which export arrays
- Replaces strings with translation function calls that access messages by indices from the arrays
Your original code stays clean and readable, while the build output is automatically internationalized.
Let's say you have:
// src/components/Welcome.jsx
function Welcome({ name }) {
return (
<div>
<h1>Welcome to our app!</h1>
<p>Hello, {name}! How are you today?</p>
<button>Get started</button>
</div>
)
}The messages are extracted into a .po file. for Spanish for example, after translation, it looks like:
#~ src/components/Welcome.jsx
msgid "Welcome to our app!"
msgstr "¡Bienvenido a nuestra aplicación!"
#~ src/components/Welcome.jsx
msgid "Hello, {0}! How are you today?"
msgstr "¡Hola, {0}! ¿Cómo estás hoy?"
#~ src/components/Welcome.jsx
msgid "Get started"
msgstr "Comenzar"Then they are compiled into a compact form optimized for loading (just an array):
export let c = ["¡Bienvenido a nuestra aplicación!",["¡Hola, ",0,"! ¿Cómo estás hoy?"],"Comenzar"]And your code is transformed into a version that accesses them by index:
// src/components/Welcome.jsx
import { _load_ } from '../locales/loader.js'
function Welcome({ name }) {
const _w_runtime_ = _load_('main')
return (
<div>
<h1>{_w_runtime_(0)}</h1>
<p>{_w_runtime_(1, [name])}</p>
<button>{_w_runtime_(2)}</button>
</div>
)
}Check out full working examples for different setups at
wuchalejs/examples to see
wuchale in action with different frameworks.
- Complex interpolations:
Welcome {userName}, you have {count} messages - Nested markup:
<p>Visit our <a href="/help">help page</a> for more info</p> - Conditional content: Handles dynamic content in templates
- Loop structures: Automatic extraction from repeated elements
- URLs: E.g.
/aboutto/de/uber-uns - Hot Module Replacement: Live translation updates during development
This is a monorepo that houses these packages:
Contributions are welcome! Please check out the test suites located inside each package for examples of supported scenarios.
This project is supported by the community. Become a sponsor and get your name or logo listed here!
Special thanks to our supporters:
And one private donor 🙏.
This project was inspired by Lingui especially some of its workflow. If you've used Lingui before, you'll find familiar concepts like extraction and compilation.
Where wuchale differs, among other things, is that you don't need to change your
code, catalogs compile smaller than any other tool (including Lingui's), and it
integrates with a wider range of frameworks.