Skip to content

Repository files navigation

l10n-tools

A modular localization toolchain for extracting translation keys from source code, syncing with translation management systems, and compiling translations into various output formats.

Features

  • Extract translation keys from multiple source types (JavaScript, TypeScript, Vue, Python, PHP, Android, iOS)
  • Sync with translation management platforms (Lokalise)
  • Compile translations into various output formats (JSON, gettext PO/MO, platform-specific)
  • Validate translation completeness and format consistency
  • Modular architecture - install only the plugins you need

Installation

# Install CLI and required plugins
npm install l10n-tools l10n-tools-extractor-vue l10n-tools-compiler-json l10n-tools-syncer-lokalise

Available Packages

Package Description
l10n-tools CLI for managing translations
l10n-tools-core Core library and infrastructure
Extractors
l10n-tools-extractor-javascript Extract from JS/TS/JSX/TSX files
l10n-tools-extractor-vue Extract from Vue.js files (vue-gettext, vue-i18n)
l10n-tools-extractor-python Extract from Python gettext functions
l10n-tools-plugin-android Extract and compile Android strings.xml
l10n-tools-plugin-ios Extract and compile iOS .strings files
Compilers
l10n-tools-compiler-json Compile to JSON formats (vue-i18n, i18next, etc.)
l10n-tools-compiler-gettext Compile to PO/MO files
Syncers
l10n-tools-syncer-lokalise Sync with Lokalise

Configuration

Create a .l10nrc file in your project root:

{
  "$schema": "https://raw.githubusercontent.com/tpcint/l10n-tools/main/packages/core/l10nrc.schema.json",
  "domains": {
    "web": {
      "type": "vue-i18n",
      "tag": "web-app",
      "locales": ["en", "ko", "ja"],
      "src-dirs": ["src"],
      "src-patterns": ["**/*.vue", "**/*.ts"],
      "outputs": [
        {
          "type": "vue-i18n",
          "target-dir": "src/locales"
        }
      ]
    }
  },
  "sync-target": "lokalise",
  "lokalise": {
    "token": "${LOKALISE_TOKEN}",
    "projectId": "your-project-id"
  }
}

The CLI automatically loads a .env file from the current working directory on startup if one exists. Existing environment variables take precedence, so values exported in your shell are not overridden.

Domain Types

Type Description
vue-gettext Vue.js with vue-gettext ($gettext, <translate>, v-translate)
vue-i18n Vue.js with vue-i18n ($t, <i18n>, <i18n-t>)
javascript JavaScript/TypeScript with custom keywords
typescript Alias for javascript
react React with i18n functions
i18next i18next translation functions
python Python gettext functions
android Android strings.xml resources
ios iOS Swift, Storyboard, and XIB files

Output Types

Type Description
json Single JSON file with all locales
json-dir Separate JSON file per locale
vue-i18n JSON with vue-i18n plural format
i18next JSON with i18next plural format
node-i18n JSON with node-i18n plural format
po-json JSON PO format
mo Compiled gettext MO files
node-gettext PO files for node-gettext
android Android strings.xml
ios iOS .strings files

iOS Property Access Patterns

For Swift code using extension-based localization like "string".localized:

extension String {
  var localized: String {
    return NSLocalizedString(self, comment: "")
  }
}

let message = "Hello, World!".localized

Add the property name with a . prefix to the keywords option:

{
  "type": "ios",
  "keywords": [".localized", ".localizedFormat"],
  "src-dir": "MyApp",
  ...
}

This extracts keys from both single-line and multi-line string literals:

"Hello".localized
"""
Multi-line
string
""".localized

Usage

Update local translations

Extract keys from source, sync with remote, and compile outputs:

l10n update

Upload changes to sync target

Extract and upload new/changed keys without modifying local files:

l10n upload

Full sync

Bidirectional sync between local and remote:

l10n sync

Check translation status

Check for untranslated entries:

l10n check
l10n check --locales ko,ja
l10n check src/components/Header.vue  # Check specific files

CLI Options

Options:
  -r, --rcfile <rcfile>              Config file path (default: .l10nrc)
  -d, --domains <domains>            Domains to process (comma separated)
  -s, --skip-validation              Skip format validation
  -b, --validation-base-locale       Base locale for validation
  -n, --dry-sync                     Simulate sync without changes
  -v, --verbose                      Verbose output
  -q, --quiet                        Minimal output
  -t, --tags <tags>                  Additional tags for keys (comma separated)

Internal commands

These commands are prefixed with _ and are intended for scripting / automation, not day-to-day use. Their flags and output are kept stable but their purpose is to be composed by other tooling.

_remoteCount — Count translations on the sync target

Query the sync target directly and report translation counts per locale, without downloading translations into the local cache. Useful for verifying upload completeness or driving dashboards.

# Sum across all domains (locale union)
l10n _remoteCount --source web

# Specific domain
l10n -d web _remoteCount --source web

# Multiple domains → one line per domain
l10n -d web,mobile _remoteCount --source web

# Filter by spec
l10n _remoteCount --source web -s untranslated
l10n _remoteCount --source web -s translated,untranslated

# Specific locales
l10n _remoteCount --source web -l en,ko

Options:

Option Description
--source <source> Source identifier to filter by. Omit to count all keys for the domain's tag.
-l, --locales <locales> Comma-separated locales (default: each domain's configured locales).
-s, --spec <spec> Comma-separated specs, ! prefix to negate. Supported: total (default), translated, untranslated.

Output format:

  • One line per domain: <domain>,<locale>:<count>,<locale>:<count>,...
  • When -d/--domains is omitted, a single aggregate line is emitted with * as the domain name. Locales are the union of each domain's locales (insertion order); a locale's count is the sum across the domains that include it.

Notes:

  • Requires a sync target that supports source listing (currently l10n-storage).
  • Counts are by (context, key) pair, matching _count semantics — a key with multiple contexts is counted per context.
  • The l10n-storage backend has no unverified flag, so unverified / !unverified specs always behave as if all entries are verified.

Requirements

  • Node.js >= 22.19.0
  • npm >= 10.9.0

License

MIT

Author

Eungkyu Song eungkyu@gmail.com

About

Localization tools

Resources

Stars

4 stars

Watchers

16 watching

Forks

Releases

Packages

Used by

Contributors

Languages