Language Detect
Green · 2026-07-02 Node + Browser Text 1.73–8.1× fasterLanguage detection powered by whatlang. Paragraph-size Green, short-string Red by design.
- Targets
- Node + Browser
- Version
- 0.1.1
Install
pnpm add @amigo-labs/language-detectBenchmarks
Trend (4 pts)Benchmark
language-detect — tweet (50 B)
- @amigo-labs/language-detect 12.14K hz · 1.73×
- franc 7.02K hz
Benchmark
language-detect — paragraph (~300 B)
- @amigo-labs/language-detect 8.84K hz · 8.06×
- franc 1.10K hz
Benchmark
language-detect — article (~11 KB)
- @amigo-labs/language-detect 4.95K hz · 5.92×
- franc 836 hz
README
@amigo-labs/language-detect
Language detection via
whatlang— ISO-639-3 codes out,franc-compatible shape.
Paragraph-sized Latin/Cyrillic/CJK detection is clear Green; short strings
(<50 B) fall back to 'und' by design because no trigram detector is
reliable there. See docs/perf-review/franc.md for the full shape analysis.
Install
pnpm add @amigo-labs/language-detect
Usage
import {
detect,
detectIfLong,
detectAll,
detectMany,
languageExists,
} from '@amigo-labs/language-detect'
detect('The quick brown fox jumps over the lazy dog')
// 'eng'
detect('Der schnelle braune Fuchs springt über den faulen Hund')
// 'deu'
detect('hi')
// 'und' — below default minLength (10 bytes)
detectIfLong('hi')
// null — prefer this over 'und' in pipelines that branch on result
detectAll('Le chat dort sur le tapis rouge')
// [{ lang: 'fra', confidence: 0.92 }]
detectMany([
'The quick brown fox…',
'Der schnelle braune Fuchs…',
'hi',
])
// ['eng', 'deu', 'und']
languageExists('eng') // true
languageExists('xyz') // false
Options
type DetectOptions = {
minLength?: number // default 10 bytes
only?: string[] // ISO-639-3 allow-list
ignore?: string[] // ISO-639-3 deny-list, applied after `only`
}
Install for the browser
The same import works in Angular, React, Vite, esbuild, and webpack ≥ 5 — the bundler picks the WASM build via the browser conditional export:
import { detect } from '@amigo-labs/language-detect'
Node consumers get the napi binary; browser consumers get the in-tarball wasm/pkg/ artifact. whatlang’s bundle is ~100 KB gzipped, well under the 500 KB browser budget.
Migration from franc
See MIGRATION.md — nearly drop-in on common cases; the confidence
scale is [0, 1] instead of franc’s internal range, and rare
franc-all languages return 'und' here (bundle-size trade-off).
License
MIT
Perf review
Perf-Review: @amigo-labs/language-detect
Status: 🟢 Green, bimodal (tweet bucket 🟡 Yellow) · Reviewed: 2026-07-02 · Version: 0.1.1
Verdict
1.73× (50 B tweet), 8.06× (~300 B paragraph), 5.92× (~11 KB article) vs. franc (bench 2026-05-22). The candidate review predicted overall Yellow — Green on paragraphs, Red on short strings. The measurement came in better on both ends: the paragraph bucket doubles the predicted 3–4×, and the tweet bucket lands at 1.73× (Yellow by the candidate’s own ≥1.5× threshold, not Red — the FFI floor did not eat the win). Trigram scoring over whatlang’s compile-time language profiles is exactly the compute-heavy, single-string-in / small-result-out shape NAPI likes.
Evidence
Measured speedup (docs/benchmarks/language-detect.json, 2026-05-22, commit b67b03d)
| Scenario | @amigo-labs/language-detect | franc | Speedup |
|---|---|---|---|
| tweet (50 B) | 12 137.51 Hz | 7 019.62 Hz | 1.73× |
| paragraph (~300 B) | 8 835.18 Hz | 1 096.13 Hz | 8.06× |
| article (~11 KB) | 4 946.72 Hz | 835.62 Hz | 5.92× |
docs/packages.jsonspeedup:"1.73–8.1× faster".- Install size: 27 KB vs
franc’s 304 KB.
Benchmark gaps
- The candidate gate’s tiny (10 B) and 200 B buckets were not benched; the 50 B and ~300 B measurements bracket them.
What shipped vs. the candidate prediction
- 87 languages (whatlang’s set) vs.
franc-all’s 414 — the mainstream-language 80/20 the candidate review scoped. - franc-compatible ISO-639-3 return codes (
'eng','deu','und', …). detectIfLongguard: inputs below the minimum length return'und'instead of a noise guess.
Divergences
Confidence scores are not comparable to franc’s (different normalization); the detected-language code matches franc on the conformance corpus for supported languages. Languages outside whatlang’s 87 fall back to 'und'. See crates/language-detect/__conformance__/divergences.md.
Pre-port assessment: franc.md
References
- Crate:
crates/language-detect - Bench shard:
docs/benchmarks/language-detect.json docs/packages.jsonspeedup:"1.73–8.1× faster"