Locale-Codes

Language and country locale data for JavaScript and TypeScript, with lookups by name, tag, ISO code, or LCID.

Library
npm
v2.0.0
74stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
58/100Fair
Development Activity76
Maintenance48
Community36
Maturity60
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
50/100Fair
Architecture55
Code Quality40
Innovation60
Learning Curve45

locale-codes is a small Node.js and TypeScript library that ships a pre-built table of language and country locale information — English names, native names, geographic locations, BCP-47-style locale tags, Windows LCID numeric identifiers, and ISO 639-1/639-2 codes — assembled by cross-referencing the windows-locale, iso639-codes, and langs packages at require-time.

Rather than parsing locale strings or hitting an external service, consumers get a flat, in-memory array (locale.all) plus a small set of lookup helpers (where, getByTag, getByLCID, getByISO6392, getByISO6391, getByName, getByNameLocal, getByLocation) for finding a single locale record by whichever identifier they already have on hand. It ships full TypeScript typings (ILocale) alongside the CommonJS implementation.

What You Get

  • A single locale.all array covering hundreds of language/country locale combinations, built at module load time.
  • Multiple lookup helpers (getByTag, getByLCID, getByISO6392, getByISO6391, getByName, getByNameLocal, getByLocation) so callers can query by whichever identifier they already have.
  • Cross-referenced data merging Windows LCID tags/ids (via windows-locale), ISO 639-1/639-2 codes (via iso639-codes), and native language names (via langs) into one normalized record shape.
  • First-class TypeScript typings (index.d.ts) exporting the ILocale interface for every field on a locale record.
  • Zero runtime network calls or file I/O — the whole table is computed once at require-time and kept in memory.

Common Use Cases

  • Language selector dropdowns - a frontend app builds a language picker by mapping over locale.all and rendering each entry’s name/local fields.
  • Normalizing user locale input - a backend service receives a tag like pt-BR from a client and calls getByTag to resolve it to a canonical language/country name for display or logging.
  • ISO code cross-referencing - a data pipeline maps a two-letter ISO 639-1 code to the corresponding three-letter ISO 639-2 code, via getByISO6391 and reading the iso639-2 field off the result.
  • Windows LCID interoperability - an app integrating with a Windows-originated system (e.g. parsing a document’s locale metadata) uses getByLCID to translate a numeric LCID into a human-readable language and location.

Under The Hood

Architecture The library is a single-file module (index.js, ~78 lines) with no internal layering — at require time it eagerly builds a merged locale table by iterating windows-locale’s keys, cross-referencing against iso639-codes by case-insensitive name match, and further cross-referencing langsall() output by ISO 639-2 code to attach a native name; the merged records are pushed into a module-level all array closed over by a small where() generic query function, and every exported getter (getByTag, getByLCID, etc.) is a thin wrapper calling where with a fixed key. There’s no dependency injection and no lazy computation — the entire table is built once as a side effect of require(), so a key/field naming change in any of the three upstream data packages would silently break the string-matching cross-references.

Tech Stack Plain CommonJS JavaScript (require/module.exports) targeting Node >=14.17.4, with no build step for the runtime code — index.js ships directly per package.json’s files array. Runtime dependencies are exactly three data-only packages: windows-locale (^1.1.0), iso639-codes (^1.0.1), and langs (^2.0.0). Dev tooling is xo (^0.30.0, an opinionated ESLint preset) for linting and tsd (^0.13.1) for validating the hand-written index.d.ts against index.test-d.ts; the test script chains xo && tsd && node test.js. A .travis.yml is the only CI config present, pointing at a now largely inactive Travis CI setup.

Code Quality Testing is minimal — test.js is a 10-line script with four bare assert.equal calls (row count check, one getByTag roundtrip, one negative-lookup check), run directly via node test.js rather than through a test framework, with no coverage of getByLCID, getByISO6392, getByLocation, or getByNameLocal. Error handling is implicit — where() returns undefined on no match rather than throwing. Type safety comes only from the parallel, hand-maintained index.d.ts, since there’s no source-level TypeScript, so types can drift from runtime behavior (e.g. local is typed optional but the code always sets it to null rather than omitting it). Style is enforced via xo, and naming is consistent, but no active CI gates these checks today.

API Design The public surface is intentionally tiny — one data array (locale.all) plus one generic query function (where(key, text)) plus seven named convenience wrappers — so a consumer can go from an ISO code or LCID straight to a locale record with a single case-insensitive call and no configuration or async handling required. Rough edges: where’s key parameter is an untyped string in the runtime code (only the .d.ts constrains it), the same generic getter is reused for structurally different lookups distinguished only by a special-cased key === 'lcid' branch, and several fields can be null with no documented fallback beyond checking for it. Documentation is a single README with usage snippets plus a full literal locale table pasted inline, and example.js/example.ts give a minimal but sufficient quick-start.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search