
Security News
upm Launches as a Fast, Tiny Package Manager Written in TypeScript
upm uses Node.js to deliver fast npm installs in about 250 KB, with a JavaScript API and security defaults.
@shipi18n/core
Advanced tools
Translation QA for i18n locale files: placeholder and plural validation, key parity, coverage, and an LLM-as-judge semantic review. Also a structure-preserving translation engine — bring your own OpenAI or Anthropic key.
The engine behind Shipi18n's translation QA — placeholder and plural validation, key parity, coverage and an LLM-as-judge semantic review — plus a structure-preserving translation engine. Open source, bring your own LLM, no account and no hosted API.
npm i @shipi18n/core # checking needs nothing else
npm i @shipi18n/core @anthropic-ai/sdk # add a provider SDK to translate or judge
import { runCheck } from '@shipi18n/core'
// deterministic, no model, no key
const { languages, totals } = runCheck({ input: './locales', source: 'en' })
import { translateJSON } from '@shipi18n/core'
const { result, stats } = await translateJSON({
content: { greeting: 'Hello {{name}}', items: 'You have {{count}} items' },
from: 'en',
to: 'es',
provider: 'anthropic', // 'anthropic' | 'openai' | a custom { complete } adapter
apiKey: process.env.ANTHROPIC_API_KEY, // optional — falls back to the provider's env var
})
console.log(result) // { greeting: 'Hola {{name}}', items: 'Tienes {{count}} elementos' }
console.log(stats) // { translated, reused, placeholderWarnings }
The API key is resolved from apiKey or, if omitted, the provider's env var
(ANTHROPIC_API_KEY / OPENAI_API_KEY). Your key is used to call your LLM directly.
The openai provider also takes a baseURL, which points it at any OpenAI-compatible
endpoint — Ollama (http://localhost:11434/v1, no key needed, fully offline), Gemini's
compatibility endpoint, Groq, Mistral, LM Studio, vLLM, or a corporate gateway:
await translateJSON({
content, from: 'en', to: 'es',
provider: 'openai',
baseURL: 'http://localhost:11434/v1', // Ollama — no apiKey required
model: 'llama3.2',
})
{{name}}, {count}, %s, %d, %1$s, $t(...), %{name}, and HTML tags.existing to reuse prior translations and only translate new/changed keys.const { result } = await translateJSON({
content: source, from: 'en', to: 'fr',
provider: 'anthropic',
existing: previousFrench, // only new/empty keys are sent to the LLM
})
Any object with a complete(prompt, opts) => Promise<string> method works — bring any model:
const myAdapter = {
name: 'my-llm',
async complete(prompt) { /* call your model, return its text */ },
}
await translateJSON({ content, from: 'en', to: 'de', provider: myAdapter })
checkTranslations is the QA half of the engine — deterministic, no model call:
import { checkTranslations } from '@shipi18n/core'
const { findings, stats } = checkTranslations({
source: { greeting: 'Hello {{name}}' },
target: { greeting: 'Hola amigo' }, // dropped {{name}}
targetLang: 'es',
})
// findings[0] → { type: 'placeholder-missing', severity: 'error', path: 'greeting', missing: ['{{name}}'], ... }
// stats → { sourceKeys, targetKeys, missing, errors, warnings, coverage }
Finding types: missing-key, orphan-key, placeholder-missing, placeholder-added,
plural-forms (vue-i18n pipe plurals), empty-value, untranslated, type-mismatch.
reviewTranslations({ source, target, from, to, provider, passes, glossary, cache }) is the
semantic layer: an LLM-as-judge pass (BYO key) with majority voting across passes, strict output
validation, and an incremental cache — unchanged pairs cost zero calls. Judge findings carry
{ path, category, note, votes, passes }.
Format adapters for mobile catalogs are exported too: parseArbBundle (Flutter ARB) and
parseXcstrings (Apple String Catalogs) normalize those files into plain locale objects that
checkTranslations understands — including %@ / %lld specifiers and plural variations.
translateJSON({ content, from, to, provider, apiKey?, model?, baseURL?, existing? }) → { result, stats }translateStrings(texts, { adapter, from, to, batchSize? }) → string[]flatten(obj) / unflatten(flat)extractPlaceholders(str) / validatePlaceholders(source, translation)getLanguageName(code)anthropicAdapter(config) / openaiAdapter(config) / resolveAdapter(provider, config)Apache-2.0
FAQs
Translation QA for i18n locale files: placeholder and plural validation, key parity, coverage, and an LLM-as-judge semantic review. Also a structure-preserving translation engine — bring your own OpenAI or Anthropic key.
The npm package @shipi18n/core receives a total of 239 weekly downloads. As such, @shipi18n/core popularity was classified as not popular.
We found that @shipi18n/core demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
upm uses Node.js to deliver fast npm installs in about 250 KB, with a JavaScript API and security defaults.

Company News
Socket is joining the OpenJS Security Stewardship Program to fund Node.js vulnerability research, maintainer remediation, and security releases.

Security News
Two compromised GitHub Actions were re-enabled with malicious tags intact, exposing thousands of downstream repositories to Mini Shai-Hulud.