{"id":29955313,"url":"https://github.com/wuchalejs/wuchale","last_synced_at":"2026-04-15T10:01:16.379Z","repository":{"id":298865537,"uuid":"1001375218","full_name":"wuchalejs/wuchale","owner":"wuchalejs","description":"Compile-time i18n toolkit that requires zero code changes and produces the smallest possible bundles. Supports React, Svelte, SolidJS, Astro, and more","archived":false,"fork":false,"pushed_at":"2026-04-15T08:20:24.000Z","size":1946,"stargazers_count":338,"open_issues_count":9,"forks_count":12,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-15T09:33:00.415Z","etag":null,"topics":["ai-translation","ast","astro","gettext","i18n","internationalization","jsx","l10n","localization","multilingual","po","preact","react","solid","solidjs","svelte","sveltekit","translation","vite","vite-plugin"],"latest_commit_sha":null,"homepage":"http://wuchale.dev","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wuchalejs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"K1DV5"}},"created_at":"2025-06-13T09:16:58.000Z","updated_at":"2026-04-15T08:20:07.000Z","dependencies_parsed_at":"2026-02-22T23:00:22.736Z","dependency_job_id":null,"html_url":"https://github.com/wuchalejs/wuchale","commit_stats":null,"previous_names":["k1dv5/wuchale","wuchalejs/wuchale"],"tags_count":218,"template":false,"template_full_name":null,"purl":"pkg:github/wuchalejs/wuchale","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wuchalejs%2Fwuchale","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wuchalejs%2Fwuchale/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wuchalejs%2Fwuchale/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wuchalejs%2Fwuchale/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wuchalejs","download_url":"https://codeload.github.com/wuchalejs/wuchale/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wuchalejs%2Fwuchale/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31835820,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-15T07:17:56.427Z","status":"ssl_error","status_checked_at":"2026-04-15T07:17:30.007Z","response_time":63,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-translation","ast","astro","gettext","i18n","internationalization","jsx","l10n","localization","multilingual","po","preact","react","solid","solidjs","svelte","sveltekit","translation","vite","vite-plugin"],"created_at":"2025-08-03T17:35:29.739Z","updated_at":"2026-04-15T10:01:16.370Z","avatar_url":"https://github.com/wuchalejs.png","language":"TypeScript","funding_links":["https://github.com/sponsors/K1DV5"],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://wuchale.dev/\"\u003e\n        \u003cimg width=\"180\" src=\"https://raw.githubusercontent.com/wuchalejs/wuchalejs.github.io/main/public/favicon.svg\" alt=\"wuchale logo\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\u003cbr/\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://npmjs.com/package/wuchale\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/wuchale?logo=npm\u0026logoColor=red\u0026color=blue\" alt=\"npm package\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/wuchalejs/wuchale/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/wuchalejs/wuchale/actions/workflows/ci.yml/badge.svg?branch=main\" alt=\"build status\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://pr.new/wuchalejs/wuchale\"\u003e\u003cimg src=\"https://developer.stackblitz.com/img/start_pr_dark_small.svg\" alt=\"Start new PR in StackBlitz Codeflow\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://wuchale.dev/chat\"\u003e\u003cimg src=\"https://img.shields.io/badge/chat-discord-blue?style=flat\u0026logo=discord\" alt=\"discord chat\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\u003cbr/\u003e\n\n# 📜`wuchale`🪶\n\n**`wuchale`** (pronounced \"wuh-cha-lay\") is a compile-time internationalization\ntoolkit that requires no code changes. Write your components naturally, and\n`wuchale` automatically extracts and replaces translatable messages at build\ntime.\n\n- **No extra syntax!** - Your normal code is enough, your codebase stays clean\n- **Tiny catalogs to bundle** - Text catalogs are just arrays, no keys necessary, like Protobuf\n- **Zero-effort integration** - Add i18n to existing projects without rewriting code\n- **Framework agnostic** - Works with React, Preact, Svelte(Kit), SolidJS, Astro, and plain JS/TS\n- **Optional AI translation** - Configurable integration for automatic on-the-fly translations\n- **Full, granular HMR support** - Live updates during development, including AI auto-translation\n- **Tiny footprint** - Very few (less than 5) additional dependencies, no bloated `node_modules`\n- **Smart extraction** - Uses AST analysis to handle nested markup, conditionals, loops, and complex interpolations\n- **Standard .po files** - Compatible with existing translation tools and workflows\n\n## A taste\n\nWith traditional i18n:\n\n```svelte\n\u003cp\u003e{t('Hello')}\u003c/p\u003e\n\u003cp\u003e\u003cTrans\u003eWelcome {userName}\u003c/Trans\u003e\u003c/p\u003e\n```\n\nWith `wuchale`:\n\n```svelte\n\u003cp\u003eHello\u003c/p\u003e\n\u003cp\u003eWelcome {userName}\u003c/p\u003e\n```\n\nNo imports, no wrappers, no annotations. `wuchale` handles everything at\ncompile time by analyzing your code and automatically extracting translatable\nstrings.\n\n## Getting started\n\nSee the [Getting Started guide](https://wuchale.dev/intro/start/) for\ninstructions specific to your project type.\n\n## How it works\n\n1. **Scans your source code** using AST and identify translatable text content\n2. **Extracts strings** into standard `.po` translation files for translators\n3. **Compiles catalogs** into compact modules which export arrays\n4. **Replaces strings** with translation function calls that access messages by indices from the arrays\n\nYour original code stays clean and readable, while the build output is automatically internationalized.\n\n## Example\n\nLet's say you have:\n\n```jsx\n// src/components/Welcome.jsx\nfunction Welcome({ name }) {\n  return (\n    \u003cdiv\u003e\n      \u003ch1\u003eWelcome to our app!\u003c/h1\u003e\n      \u003cp\u003eHello, {name}! How are you today?\u003c/p\u003e\n      \u003cbutton\u003eGet started\u003c/button\u003e\n    \u003c/div\u003e\n  )\n}\n```\n\nThe messages are extracted into a `.po` file. for Spanish for example, after translation, it looks like:\n\n```po\n#~ src/components/Welcome.jsx\nmsgid \"Welcome to our app!\"\nmsgstr \"¡Bienvenido a nuestra aplicación!\"\n\n#~ src/components/Welcome.jsx\nmsgid \"Hello, {0}! How are you today?\"\nmsgstr \"¡Hola, {0}! ¿Cómo estás hoy?\"\n\n#~ src/components/Welcome.jsx\nmsgid \"Get started\"\nmsgstr \"Comenzar\"\n```\n\nThen they are compiled into a compact form optimized for loading (just an array):\n\n```js\nexport let c = [\"¡Bienvenido a nuestra aplicación!\",[\"¡Hola, \",0,\"! ¿Cómo estás hoy?\"],\"Comenzar\"]\n```\n\nAnd your code is transformed into a version that accesses them by index:\n\n```jsx\n// src/components/Welcome.jsx\nimport { _load_ } from '../locales/loader.js'\n\nfunction Welcome({ name }) {\n  const _w_runtime_ = _load_('main')\n  return (\n    \u003cdiv\u003e\n      \u003ch1\u003e{_w_runtime_(0)}\u003c/h1\u003e\n      \u003cp\u003e{_w_runtime_(1, [name])}\u003c/p\u003e\n      \u003cbutton\u003e{_w_runtime_(2)}\u003c/button\u003e\n    \u003c/div\u003e\n  )\n}\n```\n\nCheck out full working examples for different setups at\n**[`wuchalejs/examples`](https://github.com/wuchalejs/examples)** to see\n`wuchale` in action with different frameworks.\n\n## Supported Features\n\n- **Complex interpolations**: `Welcome {userName}, you have {count} messages`\n- **Nested markup**: `\u003cp\u003eVisit our \u003ca href=\"/help\"\u003ehelp page\u003c/a\u003e for more info\u003c/p\u003e`\n- **Conditional content**: Handles dynamic content in templates\n- **Loop structures**: Automatic extraction from repeated elements\n- **URLs**: E.g. `/about` to `/de/uber-uns`\n- **Hot Module Replacement**: Live translation updates during development\n\n## Repository structure\n\nThis is a monorepo that houses these packages:\n\n| Package    | Description | Latest |\n| -------- | ------- | --- |\n| `wuchale`  | Core + CLI + Vanilla adapter    |[![wuchale](https://img.shields.io/npm/v/wuchale?logo=npm\u0026logoColor=red\u0026color=blue\")](https://npmjs.com/package/wuchale) |\n| `@wuchale/jsx` | JSX adapter (for React and SolidJS)     |[![@wuchale/jsx](https://img.shields.io/npm/v/@wuchale/jsx?logo=npm\u0026logoColor=red\u0026color=blue\")](https://npmjs.com/package/@wuchale/jsx)|\n| `@wuchale/svelte`    | Svelte adapter    |[![@wuchale/svelte](https://img.shields.io/npm/v/@wuchale/svelte?logo=npm\u0026logoColor=red\u0026color=blue\")](https://npmjs.com/package/@wuchale/svelte)|\n| `@wuchale/astro`    | Astro adapter    |[![@wuchale/astro](https://img.shields.io/npm/v/@wuchale/astro?logo=npm\u0026logoColor=red\u0026color=blue\")](https://npmjs.com/package/@wuchale/astro)|\n\n## Contributing\n\nContributions are welcome! Please check out the test suites located inside each\npackage for examples of supported scenarios.\n\n**Note**: The tests are also written in TypeScript and therefore you should have Node 22+ to run them.\n\n## Sponsors\n\nThis project is supported by the community. Become a sponsor and get your name\nor logo listed here!\n\n[![Sponsor on GitHub](https://img.shields.io/badge/Sponsor%20on-GitHub-%23ea4aaa?logo=github\u0026logoColor=white)](https://github.com/sponsors/K1DV5)\n\nSpecial thanks to our supporters:\n\n[![hayzamjs](https://avatars.githubusercontent.com/u/3922884?v=4\u0026size=48)](https://github.com/hayzamjs)\n[![p-mercury](https://avatars.githubusercontent.com/u/9084532?v=4\u0026size=48)](https://github.com/p-mercury)\n[![perdix](https://avatars.githubusercontent.com/u/1526654?v=4\u0026size=48)](https://github.com/perdix)\n\nAnd one private donor 🙏.\n\n## Inspiration\n\nThis project was inspired by [Lingui](https://lingui.dev/) especially some of\nits workflow. If you've used Lingui before, you'll find familiar concepts like\nextraction and compilation.\n\nWhere `wuchale` differs, among other things, is that you don't need to change your\ncode, catalogs compile smaller than any other tool (including Lingui's), and it\nintegrates with a wider range of frameworks.\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwuchalejs%2Fwuchale","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwuchalejs%2Fwuchale","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwuchalejs%2Fwuchale/lists"}