Write plain code
Without any need to do anything different:
Write plain code
Without any need to do anything different:
Extract and translate
Into PO files (default) and optionally live translate using AI
msgid "Hello world!"
msgstr "Hello world!"
Compile catalogs
Into arrays. No need for keys.
export let c = ["Hello world!"]
Transform
Update your code to access the translations by index
Render
Load the desired compiled catalog, and hand it to your framework
Works with your stack!
React
Preact
SolidJS
Svelte
Astro
JavaScript
TypeScript
Python*
Golang*
'use client'
export function Greeting({ username }) {
return (
<div>
<p>Hello!</p>
<p title="Welcome" class="para">
Welcome {username}!
</p>
</div>
)
}
'use client'
import { getRuntimeRx as useW_load_rx_, getRuntime as _w_load_ } from "./main.loader.js"
import W_tx_ from "@wuchale/jsx/runtime.jsx"
export function Greeting({ username }) {
const _w_runtime_ = useW_load_rx_('main')
return (
<div>
<p>{_w_runtime_(0)}</p>
<p title={_w_runtime_(1)} class="para">
<W_tx_ x={_w_runtime_.c(2)} a={[username]} />
</p>
</div>
)
}
// comment
export function Greeting({ username }) {
return (
<div>
<p>Hello!</p>
<p title="Welcome" class="para">
Welcome {username}!
</p>
</div>
)
}
// comment
import { getRuntimeRx as useW_load_rx_, getRuntime as _w_load_ } from "./main.loader.js"
import W_tx_ from "@wuchale/jsx/runtime.jsx"
export function Greeting({ username }) {
const _w_runtime_ = useW_load_rx_('main')
return (
<div>
<p>{_w_runtime_(0)}</p>
<p title={_w_runtime_(1)} class="para">
<W_tx_ x={_w_runtime_.c(2)} a={[username]} />
</p>
</div>
)
}
// comment
export function Greeting({ username }) {
return (
<div>
<p>Hello!</p>
<p title="Welcome" class="para">
Welcome {username}!
</p>
</div>
)
}
// comment
import { getRuntimeRx as useW_load_rx_, getRuntime as _w_load_ } from "./main.loader.js"
import W_tx_ from "@wuchale/jsx/runtime.solid.jsx"
const _w_runtime_ = () => useW_load_rx_('main')
export function Greeting({ username }) {
return (
<div>
<p>{_w_runtime_()(0)}</p>
<p title={_w_runtime_()(1)} class="para">
<W_tx_ x={_w_runtime_().c(2)} a={[username]} />
</p>
</div>
)
}
<script>
const { username } = $props()
</script>
<div>
<p>Hello!</p>
<p title="Welcome" class="para">
Welcome {username}!
</p>
</div>
<script>
import { getRuntimeRx as _w_load_rx_, getRuntime as _w_load_ } from "./main.loader.svelte.js"
import W_tx_ from "@wuchale/svelte/runtime.svelte"
const _w_runtime_ = $derived(_w_load_rx_('main'))
const { username } = $props()
</script>
<div>
<p>{_w_runtime_(0)}</p>
<p title={_w_runtime_(1)} class="para">
<W_tx_ x={_w_runtime_.c(2)} a={[username]} />
</p>
</div>
---
const { username } = Astro.props
---
<div>
<p>Hello!</p>
<p title="Welcome" class="para">
Welcome {username}!
</p>
</div>
---
import {getRuntime as _w_load_, getRuntimeRx as _w_load_rx_} from "./main.loader.js"
import _w_Tx_ from "@wuchale/astro/runtime.js"
const _w_runtime_ = _w_load_('astro')
const { username } = Astro.props
---
<div>
<p>{_w_runtime_(0)}</p>
<p title={_w_runtime_(1)} class="para">
{_w_Tx_({ x: _w_runtime_.c(2), a: [username] })}
</p>
</div>
// comment
export function Greeting(props) {
return {
greeting: `Hello`,
title: 'Welcome',
message: `Welcome ${props.username}!`,
}
}
import { getRuntime as _w_load_ } from "./main.loader.js"
// comment
export function Greeting(props) {
const _w_runtime_ = _w_load_('main')
return {
greeting: _w_runtime_(0),
title: _w_runtime_(1),
message: _w_runtime_(2, [props.username]),
}
}
// comment
export function Greeting(props: { username: string }) {
return {
greeting: `Hello`,
title: 'Welcome',
message: `Welcome ${props.username}!`,
}
}
import { getRuntime as _w_load_ } from "./main.loader.js"
// comment
export function Greeting(props: { username: string }) {
const _w_runtime_ = _w_load_('main')
return {
greeting: _w_runtime_(0),
title: _w_runtime_(1),
message: _w_runtime_(2, [props.username]),
}
}
msgid "Hello!"
msgstr "Hello!"
msgid "Welcome"
msgstr "Welcome"
msgid "Welcome {0}!"
msgstr "Welcome {0}!"
export let c = [
'Hello!',
'Welcome',
[ 'Welcome ', 0, '!' ],
]
Smallest Bundles
Instead of key-value pairs, compilation produces arrays accessed by indices.
Unmatched DX
HMR + optional AI translation for real-time development feedback.
Flexible catalog loading
You decide how the catalog is loaded: Async, Bundled, or custom.
Format agnostic
The default storage is Gettext PO files, widely supported and familiar to translators. But you can use anything else.
Used by projects
Do you also use it in your project? Let us know!
Companion tooling
Support
Inspiration
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.