Working with Existing Translations

Lingo.dev CLI seamlessly integrates with projects that already have translation files, preserving existing work while filling in missing translations.

When you run the CLI on a project with existing translations, it analyzes what's already translated and only generates content for missing keys, maintaining your existing translation quality and consistency.

Note: Make sure your target language files are empty and do not contain content in the source language. Having source language content in target files is a bad practice and can interfere with the translation process.

How It Works

Lingo.dev CLI compares your source content against existing target files to identify gaps. Only missing translations are generated, leaving your existing work untouched.

Example scenario:

// locales/en.json (source)
{
  "welcome": "Welcome to our app",
  "button.save": "Save",
  "button.cancel": "Cancel",
  "error.network": "Network error"
}

// locales/es.json (existing partial translations)
{
  "welcome": "Bienvenido a nuestra aplicación",
  "button.save": "Guardar"
}

Running npx lingo.dev@latest i18n generates only the missing translations:

// locales/es.json (after CLI run)
{
  "welcome": "Bienvenido a nuestra aplicación",
  "button.save": "Guardar",
  "button.cancel": "Cancelar",
  "error.network": "Error de red"
}

Your existing "welcome" and "button.save" translations remain unchanged.

First Run with Existing Translations

When you first run Lingo.dev CLI on a project with existing translations, it creates the i18n.lock file based on your current state. This lockfile tracks which content has been processed, ensuring existing translations aren't regenerated.

Workflow:

  1. Initial scan — CLI identifies existing translations in target files
  2. Gap analysis — Compares source keys against target files to find missing translations
  3. Translation generation — Creates only missing translations
  4. Lockfile creation — Records content fingerprints for all source content

Migration from legacy translation systems

Lingo.dev CLI works with translation files created by any tool, as long as they follow standard formats like JSON, YAML, or other supported file types.

Migration steps:

  1. Configure i18n.json — Set up your bucket patterns to match existing file locations
  2. Run initial translation — CLI fills in any missing translations
  3. Review and commit — Existing translations are preserved, only gaps are filled

Example migration:

// Your existing project structure
locales/
  en.json    (source)
  es.json    (partial translations from previous tool)
  fr.json    (partial translations from previous tool)

// i18n.json configuration
{
  "locale": {
    "source": "en",
    "targets": ["es", "fr"]
  },
  "buckets": {
    "json": {
      "include": ["locales/[locale].json"]
    }
  }
}

The CLI respects your existing file structure and translations.

Handling Translation Quality

Existing translations might have worse quality than translations generated by AI translation engines. Lingo.dev CLI provides options to refresh translations when needed:

Keep existing translations:

npx lingo.dev@latest i18n
# Preserves all existing translations, fills in gaps

Retranslate specific languages:

npx lingo.dev@latest i18n --force --locale es
# Regenerates all Spanish translations

Retranslate specific keys:

npx lingo.dev@latest i18n --force --key error.network
# Regenerates just the error.network key across all languages

For more information on retranslation, see Retranslation.

Empty Target Files

If you have empty target files or files with only some keys, Lingo.dev CLI treats them as partially translated and fills in missing content.

Example:

// locales/de.json (empty target file)
{}

After running the CLI, it becomes a complete translation file with all source keys translated.

Lockfile Initialization

The first run creates an i18n.lock file that reflects your existing state. This prevents the CLI from retranslating content that was already present, even if it wasn't originally generated by Lingo.dev CLI.

This lockfile ensures consistent behavior between existing and new translations going forward.