npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@webergency-utils/i18n

v0.0.2

Published

Zero-dependency, isomorphic TypeScript i18n library with math rules, array specificity, and zero-overhead Map index lookup.

Readme

@webergency-utils/i18n

A zero-dependency, isomorphic TypeScript i18n library featuring fast $O(1)$ Map index lookups, intuitive math rule selectors, dynamic template specificity scoring, and full Slavic/CLDR plural declension.

npm version license Maintenance dependencies monthly downloads OpenSSF Scorecard code coverage tests CodeQL

TL;DR

import { I18N } from '@webergency-utils/i18n';

const dict = {
    greetings: {
        hello: {
            sk: [ 'Ahoj {name}', 'Čau {name}' ],
            en: 'Hello {name}'
        }
    },
    to_men: {
        sk: {
            '#count': {
                '1': 'mužovi',
                '2n+1': 'mužíkom',
                '2-Infinity': 'mužom',
                '*': 'mužom'
            }
        },
        en: {
            '#count': {
                'one': '{count} man',
                'other': '{count} men'
            }
        }
    }
};

const i18n = new I18N({
    dictionaries: [ dict ],
    locale: 'en',
    fallbacks: [ 'sk', 'en' ]
});

// Basic lookup with template parameters
console.log( i18n.get( 'sk', 'greetings.hello', { name: 'Peter' })); // "Ahoj Peter" (or "Čau Peter")

// Slovak rule matching (count = 3 -> odd -> '2n+1' -> 'mužíkom')
console.log( i18n.get( 'sk', 'to_men', { count: 3 })); // "mužíkom"

// English CLDR plural matching (count = 5 -> 'other' -> '5 men')
console.log( i18n.get( 'en', 'to_men', { count: 5 })); // "5 men"

Installation & Setup

Install using your preferred package manager:

npm install @webergency-utils/i18n

Module Formats & Environments

The library ships dual CJS and ESM builds with complete TypeScript declaration maps .d.ts. It has zero external dependencies and runs natively across Node.js, React Native, Web Browsers, Cloudflare Workers, and Edge runtime environments.

Architecture & Internals

1. Lazy On-Demand Caching (0ms Load Overhead)

Initialization (new I18N(...)) simply stores raw dictionary references with 0ms instant startup overhead. No upfront object traversal occurs. When a translation key is queried for the first time via .get(locale, key), the resolved translation leaf is cached in #cache: Map<locale, Map<key, Leaf>> so all subsequent lookups execute in $O(1)$ constant time.

2. Dict Precedence (Last-Wins)

When multiple dictionaries are supplied in dictionaries: [ baseDict, overrideDict ], later dictionaries in the array override earlier ones (Object.assign / { ...base, ...overrides } spread behavior).

3. Rule Selector Precedence (#var)

For keys starting with # (e.g. #count), the engine matches against the scope variable value using the following precedence hierarchy:

  1. Exact: "1", "0", "male" (rank 5)
  2. Affine / Modulo Math: "2n+1", "10n+5" for integer $k \ge 0$ (rank 4)
  3. Range: "2-Infinity", "2-4" where narrower span wins (rank 3)
  4. CLDR Plural Categories: "zero", "one", "two", "few", "many" via native Intl.PluralRules (rank 2)
  5. Catch-all: "*" or "other" (rank 1)

4. Template Candidate Scoring & Random Selection

Candidate templates are filtered to discard any with missing scope variables, scored by the count of successfully resolved variables (max-score specificity), and randomly selected from the highest-scoring candidate pool.

5. TypeScript Key Autocomplete & Type Safety

Pass your dictionary interface or object type to I18N<TDictionary> for IDE key path suggestions:

const appDict = {
    greetings: {
        hello: { sk: 'Ahoj', en: 'Hello' }
    },
    to_men: {
        sk: { '#count': { '1': 'mužovi' } }
    }
};

type AppDict = typeof appDict;

const i18n = new I18N<AppDict>({ dictionaries: [ appDict ] });

// IDE suggests 'greetings.hello' | 'to_men' automatically!
i18n.get( 'sk', 'greetings.hello' );

6. Dictionary Validation Utility (validateDictionaries)

Use validateDictionaries to lint translation bundles before shipping:

import { validateDictionaries } from '@webergency-utils/i18n';

const report = validateDictionaries({
    dictionaries: [ dict ],
    locales: [ 'sk', 'en' ]
});

if( !report.valid )
{
    console.error( 'Translation validation errors:', report.errors );
}

Glossary

  • I18N: Main class managing dictionary indexing, key resolution, locale fallback chains, and exports.
  • AutoCompleteKey<T>: TypeScript utility type generating autocomplete union paths (KeyPath<T> | (string & {})).
  • validateDictionaries: Utility function linting dictionary completeness, placeholder syntax, and branch structures.
  • Leaf: A leaf translation node represented as a string, string[] (variant pool), or #var SelectorObject.
  • SelectorObject: An object mapping rule keys (1, 2n+1, 2-4, few, *) under a #varName selector key.
  • DictionaryInput: Either a multi-language dictionary object or a single-language specification { locale: 'sk', dictionary: dict }.
  • Converter: Custom variable transformation function {path%converterName:arg}.

API Reference

Class: I18N

Constructor

new I18N( options: I18NOptions )
Parameters
  • options (I18NOptions):
    • dictionaries (DictionaryInput | DictionaryInput[], required): One or more dictionary objects or single-language specs.
    • locale (string, optional): Default / last-resort fallback locale.
    • fallbacks (string[], optional): Ordered list of fallback locales.
    • converters (Record<string, Converter>, optional): Custom variable converters.
    • transform (( value: string ) => string, optional): Post-processor for all returned strings.
    • random (() => number, optional): Custom pseudo-random function (defaults to Math.random).

Method: get

get( locale: string, ...args: Array<string | object> ): string

Resolves the translation key for the specified locale. Accepts multiple string key fallbacks and scope objects.

Parameters

| Parameter | Type | Description | |---|---|---| | locale | string | Requested language code (e.g. 'sk', 'en'). | | ...args | Array<string \| object> | Translation keys in fallback order followed by scope variable objects. |

Returns

string — The resolved, interpolated translation string, or the first key string if missing.

Example
const text = i18n.get( 'sk', 'primary.key', 'fallback.key', { name: 'Peter', count: 3 });

Method: dictionary

dictionary( locale: string, path?: string ): Record<string, any>

Exports a complete, single-language object tree for locale. Fills missing leaves from the fallback locale chain while preserving array variants and #var selector objects.

Parameters

| Parameter | Type | Description | |---|---|---| | locale | string | Target language code to export. | | path | string (optional) | Subpath prefix to export (defaults to root ""). |

Returns

Record<string, any> — The exported single-language dictionary object tree.

Maintenance

This package is actively maintained.

Bug reports and pull requests are welcome. Security issues and critical regressions are prioritized. New features are considered when they align with the package's existing scope.