Skip to main content
shipi18n logo|Documentation

Core Library

@shipi18n/core is the engine every other package is built on. Use it directly when you want translation inside your own script or build step.

Install

npm install @shipi18n/core @anthropic-ai/sdk
# or
npm install @shipi18n/core openai

translateJSON

import { translateJSON } from '@shipi18n/core'

const { result, stats } = await translateJSON({
  content: { greeting: 'Hello {{name}}' },
  from: 'en',
  to: 'es',
  provider: 'anthropic',                  // 'anthropic' | 'openai' | custom adapter
  apiKey: process.env.ANTHROPIC_API_KEY,  // optional — falls back to the env var
})

console.log(result)  // { greeting: 'Hola {{name}}' }
console.log(stats)   // { translated, reused, placeholderWarnings }

Options

OptionDescription
contentThe object to translate. Nested objects and arrays are walked; non-string leaves pass through untouched.
from / toLanguage codes. to takes a single language per call.
providerProvider name or a custom { complete } adapter.
apiKeyOptional; the provider environment variable is used when omitted.
modelOptional model override.
existingPrevious translations. Keys already present are reused instead of re-translated.

Incremental translation

const { result, stats } = await translateJSON({
  content: source,
  from: 'en',
  to: 'fr',
  provider: 'anthropic',
  existing: previousFrench,   // only new or empty keys are sent to the model
})

console.log(`translated ${stats.translated}, reused ${stats.reused}`)

Checking placeholders yourself

import { validatePlaceholders } from '@shipi18n/core'

// Returns { ok, missing, added } — not an array. Check .ok, because a bare
// truthiness test on the result would always pass and silently protect nothing.
const { ok, missing, added } = validatePlaceholders(sourceString, translatedString)

if (!ok) {
  throw new Error(
    `placeholder drift: missing ${missing.join(', ') || 'none'}, ` +
    `unexpected ${added.join(', ') || 'none'}`
  )
}

translateJSON already reports drift through stats.placeholderWarnings, so you rarely need to call this yourself. Each entry is { path, source, translation, ok, missing, added } — note path, not key. Failing your build on a non-empty array is a cheap safety net.

Module format

The package is ESM. Use "type": "module", an .mjs file, or a dynamic import() from CommonJS.