Open-source localization engineering tools. Connects to Lingo.dev localization engineering platform for consistent, quality translations.
This report summarizes scanner evidence for lingodotdev/lingo.dev, a TypeScript project with 5,399 GitHub stars. SynthScan examined 121,285 lines of code across 774 source files, recording 148 pattern matches distributed across 9 syntactic categories. The legacy adjusted pattern signal is 2.0 (Low pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Payload schema: 1.0.0 · Engine: 2.0.0 · Scoring: heuristic-density-v1 · Scan date: 2026-10-31.
Can maintainers explain intent, assumptions, and trade-offs? 113 finding(s).
Are imports declared and package/API names verified? 35 finding(s).
Are wrappers, guards, and repeated structures necessary? 72 finding(s).
Which changes need focused human review? 148 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 148 distinct pattern matches across 9 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | scripts/docs/src/utils.ts | 83 | export async function createOrUpdateGitHubComment( | CODE |
| LOW | scripts/docs/src/generate-cli-docs.ts | 114 | function createBracketAwareTextNodes(text: string): PhrasingContent[] { | CODE |
| LOW | scripts/docs/src/json-schema/markdown-renderer.ts | 96 | export function makeAllowedKeysBulletNode( | CODE |
| LOW | scripts/docs/src/json-schema/markdown-renderer.ts | 171 | export function renderPropertiesToMarkdown( | CODE |
| LOW | packages/new-compiler/tests/helpers/setup-fixture.ts | 420 | export async function findTranslationServerPort(): Promise<number | null> { | CODE |
| LOW | …es/new-compiler/src/translators/lingo/model-factory.ts | 176 | export function validateAndGetApiKeys( | CODE |
| LOW | packages/new-compiler/src/plugin/cleanup.ts | 1 | export function registerCleanupOnCurrentProcess({ | CODE |
| LOW | packages/new-compiler/src/plugin/build-translator.ts | 322 | function formatCacheValidationError( | CODE |
| LOW | …ages/new-compiler/src/plugin/transform/process-file.ts | 102 | function shouldSkipTranslationForElement( | CODE |
| LOW | packages/new-compiler/src/plugin/transform/utils.ts | 266 | export function constructServerTranslationHookCall({ | CODE |
| LOW | packages/new-compiler/src/plugin/transform/metadata.ts | 67 | function isTranslatableMetadataField(fieldPath: string): boolean { | CODE |
| LOW | packages/new-compiler/src/plugin/transform/metadata.ts | 83 | function isNextGenerateMetadataFunction(path: NodePath<t.FunctionDeclaration>) { | CODE |
| LOW | packages/new-compiler/src/plugin/transform/metadata.ts | 93 | function getNextMetadataObjectOrNull( | CODE |
| LOW | packages/new-compiler/src/plugin/transform/metadata.ts | 203 | function transformMetadataFunction( | CODE |
| LOW | packages/new-compiler/src/plugin/transform/metadata.ts | 252 | export function processNextStaticMetadata( | CODE |
| LOW | packages/new-compiler/src/plugin/transform/metadata.ts | 294 | export function processNextDynamicMetadata( | CODE |
| LOW | …es/new-compiler/src/plugin/transform/parse-override.ts | 203 | export function processOverrideAttributes( | CODE |
| LOW | packages/new-compiler/src/utils/tracking-events.ts | 13 | export function sanitizeConfigForTracking(config: LingoConfig) { | CODE |
| LOW | packages/new-compiler/src/virtual/code-generator.ts | 30 | export function generateServerLocaleModule(config: LingoConfig): string { | CODE |
| LOW | packages/new-compiler/src/virtual/code-generator.ts | 41 | export function generateClientLocaleModule(config: LingoConfig): string { | CODE |
| LOW | …-compiler/src/translation-server/translation-server.ts | 840 | export async function startOrGetTranslationServer( | CODE |
| LOW | …/new-compiler/src/react/next/cookie-locale-resolver.ts | 39 | export function createNextCookieLocaleResolver( | CODE |
| LOW | …ges/new-compiler/src/react/server-only/translations.ts | 104 | export async function fetchTranslationsOnServer( | CODE |
| LOW | packages/cli/src/cli/cmd/run/execute.ts | 127 | function createWorkerStatusMessage(args: { | CODE |
| LOW | packages/cli/src/cli/cmd/run/execute.ts | 142 | function createExecutionProgressMessage(ctx: CmdRunContext) { | CODE |
| LOW | packages/cli/src/cli/utils/errors.ts | 160 | export function createPreviousErrorContext(errorDetails: ErrorDetail[]) { | CODE |
| LOW | packages/cli/src/cli/utils/cloudflare-status.ts | 23 | export function formatCloudflareStatusMessage( | CODE |
| LOW | packages/cli/src/cli/utils/buckets.ts | 395 | function buildLocalePlaceholderSegment( | CODE |
| LOW | packages/cli/src/cli/utils/find-locale-paths.ts | 35 | function findLocaleFilesWithExtension(ext: string) { | CODE |
| LOW | packages/cli/src/cli/utils/find-locale-paths.ts | 91 | function findLocaleFilesForFilename(fileName: string) { | CODE |
| LOW | packages/cli/src/cli/utils/exit-gracefully.ts | 20 | function checkForPendingOperations(): boolean { | CODE |
| LOW | packages/cli/src/cli/localizer/lingodotdev.ts | 8 | export default function createLingoDotDevLocalizer( | CODE |
| LOW | packages/cli/src/cli/loaders/xcode-stringsdict.ts | 14 | export default function createXcodeStringsdictLoader(): ILoader< | CODE |
| LOW | packages/cli/src/cli/loaders/locked-patterns.ts | 64 | export default function createLockedPatternsLoader( | CODE |
| LOW | packages/cli/src/cli/loaders/index.spec.ts | 4523 | function mockFileOperationsForPaths(input: Record<string, string>) { | CODE |
| LOW | packages/cli/src/cli/loaders/ensure-key-order.ts | 5 | export default function createEnsureKeyOrderLoader(): ILoader< | CODE |
| LOW | packages/cli/src/cli/loaders/json-dictionary.ts | 7 | export default function createJsonDictionaryLoader(): ILoader< | CODE |
| LOW | packages/cli/src/cli/loaders/android.ts | 847 | function createResourceNodeFromValue( | CODE |
| LOW | packages/cli/src/cli/loaders/android.ts | 1048 | function cloneResourceNodeFromLookup( | CODE |
| LOW | packages/cli/src/cli/loaders/android.ts | 1427 | function appendSegmentToNearestResource( | CODE |
| LOW | packages/cli/src/cli/loaders/preserved-keys.ts | 6 | export default function createPreservedKeysLoader( | CODE |
| LOW | packages/cli/src/cli/loaders/xcode-xcstrings-v2.ts | 22 | function getRequiredPluralCategories(locale: string): string[] { | CODE |
| LOW | packages/cli/src/cli/loaders/unlocalizable.ts | 9 | export default function createUnlocalizableLoader( | CODE |
| LOW | packages/cli/src/cli/loaders/plutil-json-loader.ts | 5 | export default function createPlutilJsonTextLoader(): ILoader<string, string> { | CODE |
| LOW | packages/cli/src/cli/loaders/xcode-xcstrings.ts | 5 | export default function createXcodeXcstringsLoader( | CODE |
| LOW | packages/cli/src/cli/loaders/ejs.ts | 122 | function reconstructEjsWithTranslation( | CODE |
| LOW | packages/cli/src/cli/loaders/mdx.ts | 75 | export function createDoubleSerializationLoader(): ILoader<string, string> { | CODE |
| LOW | packages/cli/src/cli/loaders/variable/index.ts | 101 | function getFormatSpecifierPattern(type: VariableLoaderParams["type"]): RegExp { | CODE |
| LOW | packages/cli/src/cli/loaders/typescript/index.ts | 64 | function extractStringsFromDefaultExport(ast: t.File): Record<string, any> { | CODE |
| LOW | packages/cli/src/cli/loaders/typescript/index.ts | 193 | function updateStringsInDefaultExport( | CODE |
| LOW | packages/cli/src/cli/loaders/typescript/index.ts | 220 | function updateStringsInObjectExpression( | CODE |
| LOW | packages/cli/src/cli/loaders/typescript/index.ts | 276 | function updateStringsInArrayExpression( | CODE |
| LOW | packages/cli/src/cli/loaders/typescript/index.ts | 320 | function updateStringsInExportedIdentifier( | CODE |
| LOW | packages/cli/src/cli/loaders/formatters/_base.ts | 11 | export function createBaseFormatterLoader( | CODE |
| LOW | packages/cli/src/cli/loaders/mdx2/frontmatter-split.ts | 6 | export default function createMdxFrontmatterSplitLoader(): ILoader<string, RawMdx> { | CODE |
| LOW | …kages/cli/src/cli/loaders/mdx2/localizable-document.ts | 5 | export default function createLocalizableMdxDocumentLoader(): ILoader< | CODE |
| LOW | packages/cli/src/cli/loaders/mdx2/section-split.ts | 87 | export default function createMdxSectionSplitLoader(): ILoader< | CODE |
| LOW | packages/cli/src/cli/loaders/mdx2/section-split.ts | 450 | function createSectionsFromBoundaries( | CODE |
| LOW | packages/cli/src/cli/loaders/mdx2/code-placeholder.ts | 35 | function ensureSurroundingImageNewlines(_content: string) { | CODE |
| LOW | packages/cli/src/cli/loaders/mdx2/code-placeholder.ts | 66 | function ensureTrailingFenceNewline(_content: string) { | CODE |
| 12 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH⚡ | packages/compiler/src/index.ts | 458 | } <your-api-key> | CODE |
| HIGH⚡ | packages/compiler/src/index.ts | 461 | }=<your-api-key> to .env file in every project that uses Lingo.dev Localization Compiler | CODE |
| HIGH⚡ | packages/compiler/src/index.ts | 464 | }=<your-api-key> in your terminal before running the compiler to set the API key for the current session | CODE |
| HIGH | packages/compiler/src/lib/lcp/api/index.ts | 460 | • Session-wide: export ${details.apiKeyEnvVar}=<your-api-key> | CODE |
| HIGH | packages/compiler/src/lib/lcp/api/index.ts | 461 | • Project-wide / CI: add ${details.apiKeyEnvVar}=<your-api-key> to your pipeline environment variables | CODE |
| HIGH⚡ | packages/compiler/src/lib/lcp/api/index.ts | 503 | 1. User-wide: Run npx lingo.dev@latest config set ${details.apiKeyConfigKey} <your-api-key> | CODE |
| HIGH⚡ | packages/compiler/src/lib/lcp/api/index.ts | 504 | 2. Project-wide: Add ${details.apiKeyEnvVar}=<your-api-key> to .env file in every project that uses Lingo.dev Lo | CODE |
| HIGH⚡ | packages/compiler/src/lib/lcp/api/index.ts | 505 | 3 Session-wide: Run export ${details.apiKeyEnvVar}=<your-api-key> in your terminal before running the compiler t | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | .claude/commands/create-bucket-docs.md | 24 | ### Step 1: Install Lingo.dev CLI | COMMENT |
| LOW⚡ | .claude/commands/create-bucket-docs.md | 34 | ### Step 2: Authenticate | COMMENT |
| LOW⚡ | .claude/commands/create-bucket-docs.md | 44 | ### Step 3: Initialize Project | COMMENT |
| LOW⚡ | .claude/commands/create-bucket-docs.md | 54 | ### Step 4: Configure [BUCKET_TYPE] Bucket | COMMENT |
| LOW | .claude/commands/create-bucket-docs.md | 77 | ### Step 5: Create File Structure | COMMENT |
| LOW | .claude/commands/create-bucket-docs.md | 101 | ### Step 6: Run Translation | COMMENT |
| LOW | .claude/commands/create-bucket-docs.md | 119 | ### Step 7: Verify Results | COMMENT |
| LOW⚡ | …es/new-compiler/src/translators/translation-service.ts | 160 | // Step 1: Determine which hashes we need to work with | COMMENT |
| LOW⚡ | …es/new-compiler/src/translators/translation-service.ts | 167 | // Step 2: Check cache first (same for all locales, including source) | COMMENT |
| LOW⚡ | …es/new-compiler/src/translators/translation-service.ts | 170 | // Step 3: Determine what needs translation/pluralization | COMMENT |
| LOW⚡ | …es/new-compiler/src/translators/translation-service.ts | 197 | // Step 4: Filter metadata to only uncached entries | COMMENT |
| LOW⚡ | …es/new-compiler/src/translators/translation-service.ts | 204 | // Step 5: Process pluralization for filtered entries | COMMENT |
| LOW | …es/new-compiler/src/translators/translation-service.ts | 216 | // Step 6: Separate overridden entries from entries that need translation | COMMENT |
| LOW⚡ | …es/new-compiler/src/translators/translation-service.ts | 239 | // Step 7: Prepare entries for translation (excluding overridden ones) | COMMENT |
| LOW⚡ | …es/new-compiler/src/translators/translation-service.ts | 245 | // Step 8: Translate or return source text | COMMENT |
| LOW⚡ | …es/new-compiler/src/translators/translation-service.ts | 302 | // Step 5: Update cache with successful translations (skip for pseudo) | COMMENT |
| LOW⚡ | …es/new-compiler/src/translators/translation-service.ts | 312 | // Step 6: Merge and return | COMMENT |
| LOW | …/new-compiler/src/translators/pluralization/service.ts | 271 | // Step 1: Detect plural candidates using pattern matching | COMMENT |
| LOW⚡ | …/new-compiler/src/translators/pluralization/service.ts | 294 | // Step 2: Generate ICU formats with batching | COMMENT |
| LOW⚡ | …/new-compiler/src/translators/pluralization/service.ts | 298 | // Step 3: Validate and update metadata entries | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | integrations/directus/docker-compose.yml | 14 | ADMIN_EMAIL: "admin@example.com" | CODE |
| LOW | …es/new-compiler/src/plugin/transform/transform.test.ts | 1579 | expect(entry.context.attributeName).toBe("placeholder"); | CODE |
| LOW | …es/new-compiler/src/plugin/transform/transform.test.ts | 1679 | expect(attributeNames).toContain("placeholder"); | CODE |
| LOW | …es/new-compiler/src/plugin/transform/transform.test.ts | 1804 | expect(entry.context.attributeName).toBe("placeholder"); | CODE |
| LOW | …ages/new-compiler/src/plugin/transform/process-file.ts | 91 | "placeholder", | CODE |
| LOW | packages/cli/demo/json/es/example.json | 11 | "name": "John Doe" | CODE |
| LOW | packages/cli/demo/json/en/example.json | 11 | "name": "John Doe" | CODE |
| LOW | packages/cli/demo/yaml/es/example.yml | 5 | display_name: "John Doe" | CODE |
| LOW | packages/cli/demo/yaml/en/example.yml | 5 | display_name: "John Doe" | CODE |
| LOW | packages/cli/src/cli/utils/element-extraction.ts | 138 | input: ["placeholder", "title"], | CODE |
| LOW | packages/cli/src/cli/utils/element-extraction.ts | 139 | textarea: ["placeholder", "title"], | CODE |
| LOW | packages/cli/src/cli/loaders/markdoc.spec.ts | 504 | expect(output["fm-attr-author"]).toBe("John Doe"); | CODE |
| LOW | packages/cli/src/cli/loaders/twig.ts | 19 | input: ["placeholder", "title", "aria-label"], | CODE |
| LOW | packages/cli/src/cli/loaders/twig.ts | 20 | textarea: ["placeholder", "title", "aria-label"], | CODE |
| LOW | packages/cli/src/cli/loaders/po/index.spec.ts | 163 | "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod " | CODE |
| LOW | packages/cli/src/cli/loaders/po/index.spec.ts | 163 | "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod " | CODE |
| LOW⚡ | packages/cli/src/cli/loaders/po/index.spec.ts | 178 | "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod " | CODE |
| LOW⚡ | packages/cli/src/cli/loaders/po/index.spec.ts | 178 | "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod " | CODE |
| LOW⚡ | packages/cli/src/cli/loaders/po/index.spec.ts | 185 | msgid "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore mag | CODE |
| LOW⚡ | packages/cli/src/cli/loaders/po/index.spec.ts | 185 | msgid "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore mag | CODE |
| LOW | packages/sdk/src/index.spec.ts | 358 | json: async () => ({ id: "usr_abc", email: "user@example.com" }), | CODE |
| LOW | packages/sdk/src/index.spec.ts | 371 | expect(result).toEqual({ id: "usr_abc", email: "user@example.com" }); | CODE |
| LOW | packages/sdk/src/index.ts | 704 | input: ["placeholder"], | CODE |
| LOW | packages/react/src/core/component.spec.tsx | 119 | const formatName = () => "John Doe"; | CODE |
| LOW | packages/compiler/src/jsx-attribute.spec.ts | 16 | Lorem ipsum <a href="https://example.com" title="Dolor link">dolor</a> sit amet. | CODE |
| LOW | packages/compiler/src/jsx-attribute.spec.ts | 21 | Lorem ipsum | CODE |
| LOW | packages/compiler/src/utils/jsx-attribute-scope.ts | 37 | "placeholder", | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | …es/new-compiler/src/translators/translation-service.ts | 160 | // Step 1: Determine which hashes we need to work with | COMMENT |
| LOW⚡ | …es/new-compiler/src/translators/translation-service.ts | 167 | // Step 2: Check cache first (same for all locales, including source) | COMMENT |
| LOW⚡ | …es/new-compiler/src/translators/translation-service.ts | 170 | // Step 3: Determine what needs translation/pluralization | COMMENT |
| LOW⚡ | …es/new-compiler/src/translators/translation-service.ts | 197 | // Step 4: Filter metadata to only uncached entries | COMMENT |
| LOW⚡ | …es/new-compiler/src/translators/translation-service.ts | 204 | // Step 5: Process pluralization for filtered entries | COMMENT |
| LOW | …es/new-compiler/src/translators/translation-service.ts | 216 | // Step 6: Separate overridden entries from entries that need translation | COMMENT |
| LOW⚡ | …es/new-compiler/src/translators/translation-service.ts | 239 | // Step 7: Prepare entries for translation (excluding overridden ones) | COMMENT |
| LOW⚡ | …es/new-compiler/src/translators/translation-service.ts | 245 | // Step 8: Translate or return source text | COMMENT |
| LOW⚡ | …es/new-compiler/src/translators/translation-service.ts | 302 | // Step 5: Update cache with successful translations (skip for pseudo) | COMMENT |
| LOW⚡ | …es/new-compiler/src/translators/translation-service.ts | 312 | // Step 6: Merge and return | COMMENT |
| LOW | …/new-compiler/src/translators/pluralization/service.ts | 271 | // Step 1: Detect plural candidates using pattern matching | COMMENT |
| LOW⚡ | …/new-compiler/src/translators/pluralization/service.ts | 294 | // Step 2: Generate ICU formats with batching | COMMENT |
| LOW⚡ | …/new-compiler/src/translators/pluralization/service.ts | 298 | // Step 3: Validate and update metadata entries | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | packages/cli/src/cli/cmd/i18n.ts | 528 | // Use robust error type detection | COMMENT |
| MEDIUM | packages/cli/src/cli/utils/errors.ts | 101 | // Type guard functions for robust error detection | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | …ckages/new-compiler/src/plugin/transform/utils.test.ts | 161 | // return Inner; | COMMENT |
| LOW | packages/cli/src/cli/utils/exec.spec.ts | 1 | import { describe, it, expect, vi } from "vitest"; | COMMENT |
| LOW | packages/cli/src/cli/loaders/mdx2/code-placeholder.ts | 1 | import { ILoader } from "../_types"; | COMMENT |
| LOW | packages/compiler/src/jsx-attribute-scope-inject.ts | 61 | t.stringLiteral(key), | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | packages/cli/src/cli/loaders/po/index.spec.ts | 83 | # This file is distributed under the same license as the PACKAGE package. | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | demo/new-compiler-vite-react-spa/analyze-bundle.sh | 13 | # Check if build exists | COMMENT |