
Security News
Axios Supply Chain Attack Reaches OpenAI macOS Signing Pipeline, Forces Certificate Rotation
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.
@timkit/languages
Advanced tools
A comprehensive language and locale definitions package providing structured data for multilingual applications. This package uses a nested architecture where languages contain their translation variants and regional locales for maximum flexibility and data-driven operation.
npm install @timkit/languages
This package uses a nested data architecture that provides a clean, hierarchical structure:
Language (e.g., Spanish)
├─ Base info: name, originalName, dir
├─ Variants: {"es": "European Spanish", "es-419": "Latin American Spanish"}
├─ Default regions: {"es": "es-es"}
└─ Regions:
├─ "es-es": {name: "Spain", code: "es", flag: "es.svg", variant: "es"}
├─ "es-mx": {name: "Mexico", code: "mx", flag: "mx.svg", variant: "es-419"}
└─ ...
This architecture provides several key benefits:
es-419)const LANGS = {
"es": {
name: "Spanish",
originalName: "Español",
dir: "ltr",
variants: {
"es": "European Spanish",
"es-419": "Latin American Spanish"
},
defaultRegion: {"es": "es-es"},
regions: {
"es-es": {name: "Spain", code: "es", flag: "es.svg", variant: "es"},
"es-mx": {name: "Mexico", code: "mx", flag: "mx.svg", variant: "es-419"},
// ... more regions
}
}
}
interface Lang {
name: string; // English name (e.g., "Spanish", "Arabic")
originalName: string; // Native name (e.g., "Español", "العربية")
dir: "ltr" | "rtl"; // Text direction
variants: Record<string, string>; // Translation variants (BCP 47)
defaultRegion: Record<string, string>; // Default region for each variant
regions: Record<string, RegionInfo>; // Regional locales
}
interface RegionInfo {
name: string; // Region name (e.g., "Mexico", "Spain")
code: string; // Country code (e.g., "mx", "es")
flag: string; // Flag SVG filename (e.g., "mx.svg")
variant: string; // Translation variant this region uses (e.g., "es-419")
}
interface DbLanguageFormat {
lang: string; // Language code (e.g., "es")
variant: string; // Variant for translation lookup (e.g., "es-419")
region: string; // Full region code (e.g., "es-mx")
url: string; // URL segment / country code (e.g., "mx")
}
import { getLang, getRegion, getVariantForRegion, LANGS } from '@timkit/languages';
// Get base language information
const lang = getLang('es');
console.log(lang);
// {
// name: "Spanish",
// originalName: "Español",
// dir: "ltr",
// variants: { "es": "European Spanish", "es-419": "Latin American Spanish" },
// defaultRegion: { "es": "es-es" },
// regions: { ... }
// }
// Get regional locale information
const region = getRegion('es-mx');
console.log(region);
// {
// name: "Mexico",
// code: "mx",
// flag: "mx.svg",
// variant: "es-419"
// }
// Get the translation variant for a region
const variant = getVariantForRegion('es', 'es-mx'); // "es-419"
import { getVariantForRegion, getRegionsByVariant } from '@timkit/languages';
// All Latin American regions share the same translation variant
console.log(getVariantForRegion('es', 'es-mx')); // "es-419"
console.log(getVariantForRegion('es', 'es-ar')); // "es-419"
console.log(getVariantForRegion('es', 'es-cl')); // "es-419"
// Spain uses a different variant
console.log(getVariantForRegion('es', 'es-es')); // "es"
// Find all regions sharing Latin American Spanish
const latinAmericanRegions = getRegionsByVariant('es-419');
console.log(latinAmericanRegions); // ["es-mx", "es-ar", "es-cl", "es-co"]
// Romanian is shared between Romania and Moldova
console.log(getVariantForRegion('ro', 'ro-ro')); // "ro"
console.log(getVariantForRegion('ro', 'ro-md')); // "ro" - same translation!
import { buildDbFormat } from '@timkit/languages';
// Get complete database format for a region
const dbFormat = buildDbFormat('es-mx');
console.log(dbFormat);
// {
// lang: "es",
// variant: "es-419", // Use this for translation lookup
// region: "es-mx", // Full region identifier
// url: "mx" // URL segment
// }
// Use in your database:
await db.siteLanguages.create({
data: {
siteId: 'site-123',
...buildDbFormat('es-mx')
}
});
import {
getLangsArray,
getLanguageRegionsArray,
getVariant
} from '@timkit/languages';
function buildLanguageSelector() {
const languages = getLangsArray();
return languages.map(lang => ({
code: lang.code,
name: lang.name,
originalName: lang.originalName,
dir: lang.dir,
regions: getLanguageRegionsArray(lang.code).map(region => ({
code: region.code,
name: region.name,
flag: `/flags/${region.flag}`,
variantName: getVariant(region.variant)
}))
}));
}
// Result structure:
// [
// {
// code: "es",
// name: "Spanish",
// originalName: "Español",
// dir: "ltr",
// regions: [
// {
// code: "es-es",
// name: "Spain",
// flag: "/flags/es.svg",
// variantName: "European Spanish"
// },
// {
// code: "es-mx",
// name: "Mexico",
// flag: "/flags/mx.svg",
// variantName: "Latin American Spanish"
// },
// ...
// ]
// },
// ...
// ]
import { isRTL, getTextDirection, getRTLLangs } from '@timkit/languages';
// Check if a language uses right-to-left text
if (isRTL('ar')) {
document.dir = 'rtl';
}
// Get text direction
const dir = getTextDirection('he'); // "rtl"
// Get all RTL language codes
const rtlLangs = getRTLLangs();
console.log(rtlLangs); // ["ar", "he", "fa", "ur"]
import {
buildDbFormat,
getLanguageCode,
getLang,
getRegion,
getRegionsByVariant
} from '@timkit/languages';
async function setupSiteLanguage(regionCode: string) {
// Get complete DB format
const dbFormat = buildDbFormat(regionCode);
if (!dbFormat) {
throw new Error(`Invalid region: ${regionCode}`);
}
// Store in database
await db.siteLanguages.create({
data: {
siteId: 'site-123',
lang: dbFormat.lang,
variant: dbFormat.variant, // Use for translation queries
region: dbFormat.region,
url: dbFormat.url
}
});
// Fetch translations using the variant
const translations = await db.translations.findMany({
where: {
siteId: 'site-123',
variant: dbFormat.variant
}
});
return translations;
}
// Example: Setting up Mexican Spanish
await setupSiteLanguage('es-mx');
// Stores: { lang: "es", variant: "es-419", region: "es-mx", url: "mx" }
// All Latin American sites will share "es-419" translations
LANGSconst LANGS: Record<string, Lang>
Nested collection of 48 languages with all their variants and regions.
Access examples:
LANGS.es.name // "Spanish"
LANGS.es.variants // { "es": "European Spanish", "es-419": "..." }
LANGS.es.regions['es-mx'] // { name: "Mexico", code: "mx", ... }
LANGS.ar.dir // "rtl"
LANG_CODESconst LANG_CODES: LangCode[] // All 48 language codes
getLang(code: string): Lang | undefinedGet complete language information including nested variants and regions.
const spanish = getLang('es');
// Returns entire Spanish object with variants and regions
isLangCode(code: string): code is LangCodeType guard to check if a string is a valid language code.
if (isLangCode('es')) {
const lang = LANGS[code]; // Type-safe
}
searchLanguage(query: string): LangCode[]Search for languages by English or native name (case-insensitive).
searchLanguage('Spanish'); // ["es"]
searchLanguage('español'); // ["es"]
searchLanguage('中文'); // ["zh"]
getVariant(variantCode: string): string | undefinedGet the display name for a translation variant.
getVariant('es-419'); // "Latin American Spanish"
getVariant('ar'); // "Modern Standard Arabic"
getVariantForRegion(langCode: string, regionCode: string): string | undefinedData-driven - Get which translation variant a region uses. No hardcoded logic - reads directly from the data.
getVariantForRegion('es', 'es-mx'); // "es-419"
getVariantForRegion('es', 'es-es'); // "es"
getVariantForRegion('en', 'en-au'); // "en-gb"
getVariantName(regionCode: string): stringGet the translation variant display name for a region.
getVariantName('es-mx'); // "Latin American Spanish"
getVariantName('en-gb'); // "British English"
getAllVariantCodes(): string[]Get all translation variant codes across all languages.
const variants = getAllVariantCodes();
// ["af", "ar", "es", "es-419", "en-gb", "en-us", ...]
getRegionsByVariant(variantCode: string): string[]Get all regions that use a specific translation variant.
getRegionsByVariant('es-419');
// ["es-mx", "es-ar", "es-cl", "es-co"]
getRegionsByVariant('en-gb');
// ["en-gb", "en-au", "en-ie"]
isValidVariant(variantCode: string): booleanCheck if a variant code exists.
isValidVariant('es-419'); // true
isValidVariant('xx-xx'); // false
getRegion(regionCode: string): RegionInfo | undefinedData-driven - Get region information. Searches through LANGS to find the region.
const mexico = getRegion('es-mx');
// {
// name: "Mexico",
// code: "mx",
// flag: "mx.svg",
// variant: "es-419"
// }
getLanguageCode(regionCode: string): string | undefinedData-driven - Extract language code from a region. Searches through LANGS to find which language owns the region.
getLanguageCode('es-mx'); // "es"
getLanguageCode('en-us'); // "en"
getLanguageCode('invalid'); // undefined
getAllRegionCodes(): string[]Get all region codes across all languages.
const regions = getAllRegionCodes();
// ["af-za", "af-na", "ar-sa", "ar-eg", ...]
isValidRegion(regionCode: string): booleanCheck if a region code exists.
isValidRegion('es-mx'); // true
isValidRegion('xx-xx'); // false
buildDbFormat(regionCode: string): DbLanguageFormat | undefinedBuild complete database storage format from a region code.
const dbFormat = buildDbFormat('es-mx');
// {
// lang: "es",
// variant: "es-419",
// region: "es-mx",
// url: "mx"
// }
getLanguageWithDefaults(langCode: string)Get complete language info with default selections pre-populated.
const spanish = getLanguageWithDefaults('es');
// {
// lang: { ... full Spanish object },
// defaultVariant: "es",
// defaultRegion: "es-es",
// defaultDbFormat: { lang: "es", variant: "es", region: "es-es", url: "es" }
// }
getLanguageVariants(langCode: string): Record<string, string> | undefinedGet all translation variants for a specific language.
getLanguageVariants('es');
// { "es": "European Spanish", "es-419": "Latin American Spanish" }
getLanguageRegions(langCode: string): Record<string, RegionInfo> | undefinedGet all regions for a specific language.
const spanishRegions = getLanguageRegions('es');
// {
// "es-es": { name: "Spain", code: "es", flag: "es.svg", variant: "es" },
// "es-mx": { name: "Mexico", code: "mx", flag: "mx.svg", variant: "es-419" },
// ...
// }
getLanguageRegionsArray(langCode: string)Get language regions as an array.
const regions = getLanguageRegionsArray('es');
// [
// { code: "es-es", name: "Spain", flag: "es.svg", variant: "es" },
// { code: "es-mx", name: "Mexico", flag: "mx.svg", variant: "es-419" },
// ...
// ]
getDefaultRegion(langCode: string): string | undefinedGet the default region for a language.
getDefaultRegion('es'); // "es-es"
getDefaultRegion('en'); // "en-gb"
getDefaultRegionForVariant(langCode: string, variantCode: string)Get the default region for a specific variant.
getDefaultRegionForVariant('es', 'es'); // "es-es"
getDisplayName(regionCode: string): stringGet full display name combining language and region.
getDisplayName('es-mx'); // "Spanish (Mexico)"
getDisplayName('en-us'); // "English (United States)"
getFlagPath(regionCode: string): stringGet the flag SVG filename for a region.
getFlagPath('es-mx'); // "mx.svg"
getTextDirection(langCode: string): "ltr" | "rtl"Get text direction for a language.
getTextDirection('ar'); // "rtl"
getTextDirection('en'); // "ltr"
isRTL(langCode: string): booleanCheck if a language uses right-to-left text.
isRTL('ar'); // true
isRTL('he'); // true
isRTL('en'); // false
getRTLLangs(): LangCode[]Get all RTL language codes.
getRTLLangs(); // ["ar", "he", "fa", "ur"]
getLTRLangs(): LangCode[]Get all LTR language codes (44 languages).
getLangsArray(): Array<Lang & { code: LangCode }>Convert LANGS to array format with language codes.
const langs = getLangsArray();
// [
// {
// code: "es",
// name: "Spanish",
// originalName: "Español",
// dir: "ltr",
// variants: { ... },
// regions: { ... }
// },
// ...
// ]
getVariantsArray(): Array<{ code: string; name: string; lang: string }>Get all variants as an array with their parent language.
const variants = getVariantsArray();
// [
// { code: "es", name: "European Spanish", lang: "es" },
// { code: "es-419", name: "Latin American Spanish", lang: "es" },
// ...
// ]
getRegionsArray(): Array<RegionInfo & { locale: string; lang: string }>Get all regions as an array with full locale codes and parent language.
const regions = getRegionsArray();
// [
// {
// locale: "es-mx",
// lang: "es",
// name: "Mexico",
// code: "mx",
// flag: "mx.svg",
// variant: "es-419"
// },
// ...
// ]
The package includes 48 languages with multiple translation variants for languages with regional differences.
es): Spaines-419): Mexico, Argentina, Chile, Colombiaen-gb): United Kingdom, Ireland, Australiaen-us): United States, Canadapt): Portugalpt-br): Brazilfr): Francefr-ca): Canadazh-hans): Chinazh-hant): TaiwanMultiple regions share the same translation to reduce duplication:
ro): Romania, Moldovaar): Saudi Arabia, Egypt, UAEde): Germany, Austria, Switzerlandnl): Netherlands, Belgiumbn): Bangladesh, Indiasw): Kenya, Tanzaniaaf): South Africa, NamibiaAfrican Languages:
Arabic (RTL):
Asian Languages:
European Languages:
Middle Eastern Languages (RTL):
Other:
Full TypeScript support with comprehensive type definitions:
import type {
Lang,
RegionInfo,
DbLanguageFormat,
LangCode
} from '@timkit/languages';
// Type-safe access
function setupLanguage(langCode: LangCode) {
const lang = LANGS[langCode]; // Fully typed
// ...
}
// Type guard for runtime validation
function handleUserInput(input: string) {
if (isLangCode(input)) {
// input is now typed as LangCode
setupLanguage(input);
}
}
All functions are data-driven with no hardcoded logic:
getLanguageCode() - Searches LANGS to find which language owns a regiongetVariantForRegion() - Reads variant directly from region datagetRegion() - Searches LANGS to find region informationBenefits:
Supports both CommonJS and ES Modules:
// ESM
import { LANGS, getLang, buildDbFormat } from '@timkit/languages';
// CommonJS
const { LANGS, getLang, buildDbFormat } = require('@timkit/languages');
Comprehensive test suite with 89 tests:
npm test # Run all tests
npm run test:watch # Watch mode
npm run test:coverage # With coverage
npm install # Install dependencies
npm run build # Build for production (CJS, ESM, TypeScript definitions)
npm run dev # Development mode with watch
npm test # Run tests
MIT
FAQs
Language definitions and utilities for internationalization
We found that @timkit/languages 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.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.

Security News
Open source is under attack because of how much value it creates. It has been the foundation of every major software innovation for the last three decades. This is not the time to walk away from it.

Security News
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.