🌍 📖 A readable, automated, and optimized (2 kb) internationalization for JavaScript
Linguijs
Lingui is a lightweight, open-source internationalization (i18n) library for JavaScript and TypeScript. It brings compile-time macros and a CLI for message extraction to React, React Native, Vue, SolidJS, Astro, Svelte, and Node.js.
About 2 kB gzipped core · 6M+ npm downloads a month · MIT licensed
Documentation · Quick Start · Why Lingui · Support · Contribute · License
Quick Start
npm install @lingui/core @lingui/react
npm install --save-dev @lingui/cli
Lingui macros run at build time, so add the macro plugin for your transpiler and create a lingui.config.js. The installation guide covers both in a few minutes.
Then wrap the text you want to translate in the Trans macro. There are no message IDs to invent and no separate JSON file to keep in sync:
import { i18n } from "@lingui/core"
import { I18nProvider } from "@lingui/react"
import { Trans } from "@lingui/react/macro"
import { messages } from "./locales/en/messages"
i18n.load("en", messages)
i18n.activate("en")
export function App() {
return (
<I18nProvider i18n={i18n}>
<Trans>
Read the <a href="https://lingui.dev">documentation</a> for more info.
</Trans>
</I18nProvider>
)
}
Extract the messages into PO catalogs, translate them, then compile the catalogs into optimized runtime output:
npx lingui extract
npx lingui compile
After translation, the Czech catalog in src/locales/cs/messages.po looks like this. The <0> tag stands for the <a> element, so translators never touch your markup:
#: src/App.jsx:12
msgid "Read the <0>documentation</0> for more info."
msgstr "Přečtěte si <0>dokumentaci</0> pro více informací."
Continue with the React tutorial, or jump to React Server Components, React Native, SolidJS, or plain JavaScript. Working projects for Vite, Next.js, Remix, TanStack Start, React Native and more live in the examples directory.
Why Lingui
In key-based i18n libraries you invent a key, put the text in a JSON file, and reference the key from the code. With Lingui, the text stays where it is read:
// Key-based i18n: the code holds a key, the text lives somewhere else
<h1>{t("dashboard.welcome.title")}</h1>
// Lingui: the text is the source of truth, the catalog is generated from it
<h1>
<Trans>Welcome back, {name}</Trans>
</h1>
The code reads like the UI it renders, and reviewers see the actual copy in the diff. Nobody has to name keys or look up what a key means. Running lingui extract regenerates the catalog from the source, so new messages are added and removed ones are marked obsolete without any manual bookkeeping. Translators get the real sentence with named placeholders, plus any comments and context you add. Message IDs are stable hashes generated at build time, and explicit IDs are available when you need them.
On top of that:
Rich text without workarounds. React components inside a message are as easy as writing JSX. Translators see numbered tags, and the catalog stays in sync with your components.
Compiled, not parsed at runtime. Catalogs are compiled ahead of time, so the runtime ships without a MessageFormat parser. Core
, React bindings
.
One library for the whole stack.
@lingui/coreworks in any JavaScript project.@lingui/reactadds components and hooks, including React Server Components support, and@lingui/solidbrings native SolidJS bindings. React Native uses the same extract-and-compile workflow, Vue single-file components are supported through@lingui/extractor-vue, and Astro and Svelte work through community packages.Standard formats and real tooling. Translations live in PO files by default, which almost every translation tool understands, or in JSON, CSV, or a custom format. Messages carry comments and context for translators and machine translation. The CLI extracts, compiles and validates, the Vite plugin compiles catalogs on the fly, the SWC plugin replaces Babel, and the ESLint plugin catches common mistakes.
Who Uses Lingui
Lingui runs in production at Bluesky, ElevenLabs, Linkerd, GDevelop, Documenso, Gamma, Twenty, Superset, Notesnook, Inkeep and many more. See the showroom for more, and add your project if it is missing.
Requirements
- Node.js 22.19 or newer.
- Lingui 6 packages are ESM-only, except
@lingui/metro-transformer, which stays CommonJS. Modern bundlers and Node.js versions withrequire(esm)handle this transparently. See the migration guide. - Macros need Babel with
@lingui/babel-plugin-lingui-macroor SWC with@lingui/swc-plugin. @lingui/reactsupports React 16.14 and newer, including React 19.
Docs for AI Agents
- Every documentation page is available as Markdown by appending
.mdto its URL, for example lingui.dev/installation.md. - lingui.dev/llms.txt indexes the docs and lingui.dev/llms-full.txt contains them in full.
- Context7 serves the latest docs over MCP. Add
use context7to a prompt. lingui/skillspackages Lingui best practices as Agent Skills for Claude Code, Cursor, Codex, Gemini CLI, GitHub Copilot and other compatible agents. Install withnpx skills add lingui/skills.
See i18n with AI for the details.
Support
If you are having issues, please let us know.
- Join us on Discord to chat with the community.
- Ask questions on StackOverflow and mark it with the
linguijstag. - If something doesn't work as documented, documentation is missing or if you just want to suggest a new feature, create an issue.
- You can also Ask Lingui JS Guru, it is a Lingui JS focused AI to answer your questions.
Contribute
Contribution to open-source project is everything from spreading the word, writing documentation to implement features and fixing bugs.
- Do you use Lingui in production site? Let us know!
- Have you seen any interesting talk or article about i18n? Share it!
- Have you found a bug or do you want to suggest a new feature? Create an issue!
- Do you want to improve the docs and write some code? Read the contributors guide and send a PR!
Contributors
This project exists thanks to all the people who contribute. [Contribute].
License
The project is licensed under the MIT license.