Top Related Projects
🌍 All in one i18n extension for VS Code
i18next: learn once - translate everywhere
🌍 📖 A readable, automated, and optimized (2 kb) internationalization for JavaScript
The monorepo home to all of the FormatJS related libraries, most notably react-intl.
Give your JavaScript the ability to speak many languages.
Quick Overview
Inlang is an open-source localization solution for web applications. It provides a comprehensive set of tools and services to manage translations, integrate localization into development workflows, and streamline the process of creating multilingual applications.
Pros
- Offers a complete ecosystem for localization, including a CLI, SDK, and visual editor
- Integrates seamlessly with popular web frameworks and build tools
- Provides real-time collaboration features for translators and developers
- Supports various file formats and custom plugins for extended functionality
Cons
- Learning curve may be steep for beginners due to the comprehensive nature of the toolset
- Documentation could be more extensive, especially for advanced use cases
- Limited support for non-web-based applications
- Some features may require a paid subscription for larger projects or teams
Code Examples
- Installing the Inlang CLI:
npm install -g @inlang/cli
- Initializing an Inlang project:
inlang init
- Using the Inlang SDK in a React component:
import { useTranslation } from '@inlang/sdk-js'
function MyComponent() {
const { t } = useTranslation()
return <h1>{t('greeting', 'Hello, World!')}</h1>
}
- Extracting messages from source code:
inlang extract
Getting Started
To get started with Inlang:
-
Install the Inlang CLI:
npm install -g @inlang/cli -
Initialize a new Inlang project in your application directory:
cd your-project inlang init -
Install the Inlang SDK for your framework (e.g., React):
npm install @inlang/sdk-js -
Use the SDK in your code (see example 3 above).
-
Extract messages and manage translations using the Inlang CLI and web interface.
For more detailed instructions and advanced usage, refer to the official Inlang documentation.
Competitor Comparisons
🌍 All in one i18n extension for VS Code
Pros of i18n-ally
- Extensive IDE integration with support for Visual Studio Code
- Robust features for managing translations, including auto-completion and inline annotations
- Active community and regular updates
Cons of i18n-ally
- Limited to specific file formats and frameworks
- Requires more setup and configuration compared to inlang
- Less focus on collaborative workflows and team-based localization
Code Comparison
i18n-ally configuration:
{
"i18n-ally.localesPaths": ["locales"],
"i18n-ally.keystyle": "nested",
"i18n-ally.sortKeys": true
}
inlang configuration:
{
"sourceLanguageTag": "en",
"languageTags": ["en", "de", "fr"],
"modules": ["@inlang/plugin-json"]
}
While i18n-ally offers more granular control over IDE-specific features, inlang's configuration is more focused on project-wide settings and language management. i18n-ally excels in providing a comprehensive IDE experience, whereas inlang aims for a more streamlined and collaborative approach to localization across different platforms and tools.
i18next: learn once - translate everywhere
Pros of i18next
- Mature and widely adopted internationalization framework
- Extensive ecosystem with plugins and integrations
- Supports multiple languages and pluralization
Cons of i18next
- Steeper learning curve for complex configurations
- Can be overkill for smaller projects
- Requires manual management of translation files
Code Comparison
i18next:
import i18n from 'i18next';
i18n.init({
lng: 'en',
resources: {
en: { translation: { key: 'Hello' } },
de: { translation: { key: 'Hallo' } }
}
});
console.log(i18n.t('key')); // Output: Hello
inlang:
import { i18n } from '@inlang/sdk-js';
const messages = {
en: { hello: 'Hello' },
de: { hello: 'Hallo' }
};
i18n.init({ messages });
console.log(i18n.t('hello')); // Output: Hello
Both libraries offer similar functionality for basic internationalization, but i18next provides more advanced features out of the box. inlang focuses on simplicity and ease of use, making it potentially more suitable for smaller projects or those new to i18n. i18next's extensive ecosystem and long-standing presence in the community give it an edge for complex, large-scale applications.
🌍 📖 A readable, automated, and optimized (2 kb) internationalization for JavaScript
Pros of js-lingui
- More mature project with a larger community and ecosystem
- Extensive documentation and examples for various use cases
- Supports multiple frameworks including React, Vue, and Svelte
Cons of js-lingui
- Limited support for non-JavaScript environments
- Requires more setup and configuration compared to inlang
- Less focus on collaborative translation workflows
Code Comparison
js-lingui:
import { t } from "@lingui/macro";
function Welcome() {
return <h1>{t`Welcome to our app!`}</h1>;
}
inlang:
import { t } from "@inlang/sdk-js";
function Welcome() {
return <h1>{t("welcome")}</h1>;
}
Both libraries offer similar syntax for basic translation, but js-lingui uses template literals while inlang uses function calls with string keys. inlang's approach may be more suitable for larger projects with many translatable strings, as it allows for easier management and organization of translations.
js-lingui provides more advanced features out-of-the-box, such as pluralization and date/number formatting, while inlang focuses on simplicity and ease of integration with various tools and services in the localization workflow.
The monorepo home to all of the FormatJS related libraries, most notably react-intl.
Pros of formatjs
- Mature and widely adopted project with extensive documentation
- Supports a broad range of internationalization features beyond just translation
- Integrates well with popular frameworks like React and Angular
Cons of formatjs
- Steeper learning curve due to its comprehensive feature set
- Can be overkill for simpler projects that only need basic translation functionality
- Requires more setup and configuration compared to lightweight alternatives
Code Comparison
formatjs:
import { FormattedMessage } from 'react-intl';
<FormattedMessage
id="welcome"
defaultMessage="Welcome, {name}!"
values={{ name: 'John' }}
/>
inlang:
import { t } from '@inlang/sdk-js';
t('welcome', { name: 'John' });
Summary
formatjs is a robust internationalization library with extensive features, making it suitable for complex applications. However, its complexity may be unnecessary for simpler projects. inlang offers a more streamlined approach to translation, which can be beneficial for projects with basic localization needs. The choice between the two depends on the specific requirements of your project and the level of internationalization features needed.
Give your JavaScript the ability to speak many languages.
Pros of Polyglot.js
- Lightweight and focused on client-side translation
- Simple API for easy integration into web applications
- Supports pluralization and interpolation out of the box
Cons of Polyglot.js
- Limited to JavaScript environments
- Lacks advanced features for managing complex localization workflows
- No built-in support for machine translation or collaborative editing
Code Comparison
Polyglot.js:
import Polyglot from 'node-polyglot';
const polyglot = new Polyglot();
polyglot.extend({"hello": "Hello"});
console.log(polyglot.t("hello")); // Output: Hello
Inlang:
import { createInstance } from '@inlang/sdk';
const i18n = await createInstance({
projectId: 'your-project-id'
});
console.log(i18n.t('hello')); // Output: Hello
Key Differences
- Inlang offers a more comprehensive solution for managing the entire localization process, including project management and collaboration features.
- Polyglot.js is more focused on providing a simple translation library for JavaScript applications.
- Inlang supports multiple platforms and languages, while Polyglot.js is primarily designed for JavaScript environments.
- Inlang includes features like machine translation and real-time collaboration, which are not available in Polyglot.js.
Both libraries serve different needs in the localization ecosystem, with Polyglot.js being a lightweight option for simple translation tasks and Inlang offering a more robust solution for complex, multi-platform localization projects.
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
inlang
The open format TMS (translation management system)
ð¹ï¸ Apps
·
ð Docs
·
ð Discord
·
ð Twitter
1.9k+ GitHub stars · 395k+ weekly npm downloads · 110+ contributors
Used across the inlang ecosystem by teams at
Inlang is the open format TMS (translation management system).
Store localization as a vendor-neutral .inlang project that can be read and written by TMS workflows, editors, CI, runtimes, plugins, and AI agents.
.inlang can be a packed project.inlang file or an unpacked project.inlang/ directory. @inlang/sdk is the reference implementation for reading and writing both representations. Inlang is the ecosystem around that format: plugins, editor workflows, CI checks, runtime integrations, and versioning via Lix.
Inlang is a fit when engineering, localization, design, CI, and automation need to work on the same localization data. If you need a fully managed enterprise localization suite with built-in vendor management, translation memory, glossary workflows, assignments, and procurement features, evaluate inlang as an open localization format rather than a full replacement for every enterprise TMS function.
What inlang gives your team
- Open file/directory localization source of truth
- One project model for bundles, messages, variants, locales, settings, and metadata
- Translator-friendly editing through tools like Fink
- SDK access for editors, CLIs, CI checks, runtimes, plugins, and AI agents
- CI checks for missing translations and placeholder issues
- Compatibility with JSON, ICU MessageFormat, i18next, and XLIFF
- Review, history, change proposals, and rollback via Lix
- Runtime integration through tools like Paraglide
What you adopt
| Layer | What it is |
|---|---|
| inlang | Open localization format and ecosystem |
.inlang | Canonical project file or directory format |
@inlang/sdk | Read/write API for editors, CLIs, CI checks, runtimes, plugins, and agents |
| Plugins | Compatibility layer for JSON, ICU MessageFormat, i18next, XLIFF, and other file formats |
| Lix | Versioning, history, review, change proposals, rollback, and merging |
| Tools | Fink, Sherlock, Parrot, CLI, and Paraglide workflows that read/write .inlang |
Choose your path
- Building an app runtime? Use Paraglide to compile from
.inlang. - Giving translators a UI? Use Fink to edit
.inlangwithout requiring Git. - Adding CI or automation? Use the CLI and SDK on the same project data.
- Building an editor, migration, report, plugin, runtime, or AI agent? Use
@inlang/sdkinstead of inventing another i18n schema. - Keeping existing JSON, ICU, i18next, or XLIFF files? Connect them through plugins while
.inlangremains the shared project model.
Build on top of inlang
If you are building localization tooling or generating localization code, target the .inlang project with @inlang/sdk. Your output will work with the same data model used by editors, CI checks, runtimes, plugins, and translation workflows.
For coding agents:
- Find an existing
project.inlangfile orproject.inlang/directory before creating new locale files. - Load and update bundles, messages, variants, locales, settings, and metadata through
@inlang/sdk. - Treat JSON, ICU, i18next, and XLIFF files as compatibility files connected through plugins.
- Do not invent a custom
locales/en.jsonschema when a.inlangproject already exists.
Messages, variants, and locale data live in the .inlang database. External translation files such as messages/en.json are compatibility files connected through plugins.
There are two representations:
project.inlang # canonical packed file
project.inlang/ # Git-friendly unpacked representation
âââ settings.json # locales, plugins, file patterns; kept in Git
âââ .gitignore # generated; ignores everything except settings.json
âââ README.md # generated; explains this folder to coding agents
âââ .meta.json # generated SDK metadata
âââ cache/ # plugin cache, created when plugins are loaded
project.inlang is the canonical packed file and portable representation. project.inlang/ is the Git-friendly unpacked representation used for review and repository workflows. Both represent the same localization project; the SDK handles reading and writing them.
The problem
Traditional TMSs make a vendor database the localization source of truth. Translation files become exports.
Common translation files like JSON, YAML, ICU, or XLIFF are good at storing messages. But they do not describe the whole localization project.
Once multiple tools need to read and write the same project, plain translation files start to miss important information:
- Bundles, variants, selectors, locales, settings, and metadata
- CRUD operations and queries without custom parsing
- Review state, history, change proposals, and rollback
- Tool and plugin configuration shared by editors, CI, runtimes, and agents
Without one shared format, every tool invents its own file structure, sync logic, and collaboration workflow.
Even basic import/export for translation file formats gets duplicated across tools instead of being shared.
The result is fragmented tooling:
- Switching tools requires migrations and refactoring
- Cross-team work requires manual exports and hand-offs
- Automating workflows requires custom scripts and glue code
ââââââââââââ âââââââââââââ ââââââââââââ
â i18n lib ââââââââââTranslationâââââââââââ CI/CD â
â â â Tool â âAutomationâ
ââââââââââââ âââââââââââââ ââââââââââââ
Every tool has its own format, its own sync, its own collaboration layer. Cross-team work? Manual exports and hand-offs.
The solution
Inlang makes the localization file the source of truth. The TMS becomes a layer around the format, not the owner of the data.
It provides:
- A message-first structure and SDK for CRUD operations
- Storage that tools can search, update, and report on
- Plugins to import/export formats like JSON, ICU MessageFormat v1, i18next, and XLIFF so that file-format support can be shared instead of reimplemented in every tool
- Versioning, history, review, change proposals, and rollback via lix
Core data model:
- Bundle â one translatable unit across locales
- Message â locale-specific translation for a bundle
- Variant â text pattern plus selector matches
ââââââââââââ âââââââââââââ ââââââââââââââ
â i18n lib â âTranslationâ â CI/CD â
â â â Tool â â Automation â
ââââââ¬ââââââ âââââââ¬ââââââ âââââââ¬âââââââ
â â â
âââââââââââ â ââââââââââââ
â¼ â¼ â¼
ââââââââââââââââââââââââââââââââââââ
â .inlang file â
ââââââââââââââââââââââââââââââââââââ
The result:
- Switch between
.inlang-compatible tools with less migration work - Cross-team work without hand-offs â developers, translators, and designers all edit the same source
- Automation gets SDK-readable project data instead of one-off glue code
- Keep your preferred message format â plugins handle import/export
Translators do not need to work directly with files or Git. Editor-friendly apps and workflows operate on the same open localization data.
If you only need an app runtime and a couple of translation files, JSON or your current i18n setup may already be enough. Use inlang when localization becomes shared work: multiple tools, teams, automations, or agents need to use the same localization data.
How inlang compares
Inlang is an open-format TMS for software teams: localization data lives in a portable .inlang file or directory, with TMS workflows layered around it.
| Approach | Source of truth | Best for | Tradeoff |
|---|---|---|---|
| Traditional TMS | Vendor database | Managed translation workflows, vendors, assignments, and enterprise localization ops | Translation files become synced exports; migration, automation, and CI depend on the vendor |
| Runtime i18n libraries | App dictionaries or compiled catalogs | Rendering translations in the app | Runtime lookup is solved, but localization workflow data is still scattered |
| Translation files only | JSON, YAML, ICU, i18next, XLIFF, etc. | Small apps and simple runtime lookup | Teams maintain their own schema, validation, sync logic, and collaboration workflows |
| inlang | .inlang file or directory | Software teams that want portable localization data with TMS workflows | Requires adopting the .inlang model; existing JSON, ICU, i18next, and XLIFF files connect through plugins |
Inlang gives tools, CI, translators, and automation one open format to work on instead of syncing separate exports.
How teams use inlang
A typical software localization workflow looks like this:
- Developers add or update messages in source files, apps, or
.inlangtooling. - The
.inlangproject becomes the shared localization source of truth. - CI checks for missing translations, placeholder mismatches, and message-format issues.
- Translators and reviewers edit translations in tools that read and write
.inlang, such as Fink, without working directly in Git. - Lix records localization changes, review history, change proposals, merges, and rollback points.
- Runtime tools such as Paraglide compile from the same
.inlangsource when the app ships.
| Layer | What it provides |
|---|---|
.inlang | Open localization format and source of truth |
@inlang/sdk | Read/write API for editors, CI, agents, and automations |
| Plugins | Compatibility with JSON, ICU, i18next, XLIFF, and other existing message formats |
| Lix | History, review, change proposals, rollback, and merging |
| CLI / CI | Checks for missing translations, placeholders, and message-format issues |
| Editor tools | Translation and review workflows without requiring translators to use Git |
| Runtime tools | App integration from the same localization source, for example through Paraglide |
This is different from a traditional TMS where the vendor database owns the localization state and translation files are exports. In inlang, the localization project remains portable; TMS workflows operate around the open format.
Tools in the inlang ecosystem
These tools read and write .inlang for different parts of the localization lifecycle.
- Paraglide â JS/TS runtime that compiles messages from
.inlang - Fink â web editor for
.inlangprojects - Sherlock â VS Code extension that reads
.inlangprojects - Parrot â Figma plugin that connects design text to
.inlang - CLI â linting, machine translation, and CI workflows for
.inlang
Read and write .inlang
import { loadProjectFromDirectory, loadProjectInMemory } from "@inlang/sdk";
import fs from "node:fs/promises";
const packedProject = await loadProjectInMemory({
blob: await fs.readFile("./project.inlang"),
});
// Loads the Git-friendly unpacked representation.
const unpackedProject = await loadProjectFromDirectory({
path: "./project.inlang",
});
const messages = await packedProject.db.selectFrom("message").selectAll().execute();
Contributing
There are many ways you can contribute to inlang! Here are a few options:
- Star this repo
- Create issues every time you feel something is missing or goes wrong
- Upvote issues with ð reaction so we know what the demand for a particular issue to prioritize it within the roadmap
If you would like to contribute to the development of the project, please refer to our Contributing guide.
All contributions are highly appreciated. ð
Top Related Projects
🌍 All in one i18n extension for VS Code
i18next: learn once - translate everywhere
🌍 📖 A readable, automated, and optimized (2 kb) internationalization for JavaScript
The monorepo home to all of the FormatJS related libraries, most notably react-intl.
Give your JavaScript the ability to speak many languages.
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot