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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@janek26/i18n

v1.0.15

Published

@janek26/i18n === ![Picture of a simple usecase](https://raw.githubusercontent.com/janek26/i18n/master/images/carbon.png "Simple usecase") That's it. The rest is optional.

Downloads

147

Readme

@janek26/i18n

Picture of a simple usecase That's it. The rest is optional.

Build Status NPM Version Size Issues

This way you can use i18n today and implement the details another time!

Getting started with i18n

import { t, p, mod, setConfig } from '.'

// (optional) Init resources
setConfig({
  lng: ['de', 'en'],  // sorted by priority (fallback)
  resources: {
    // async resources needs to be a function returning a promise
    // the function will just be called when the resource is needed (in lng)
    en: () => returnsPromiseWhichResolvesToTheSameFormatAsBelow(),
    // sync resource
    de: {
      translation: {
        'Hello ${1}!': 'Moin ${1}!',
      },
      modifier: {
        int: int => int * 10,
      },
      plural: {
        '${1} tree': c => (c === 1 ? `ein Baum` : `${c} Bäume`),
      },
    },
  },
  // Could be used to extract (unknown) keys
  onKey: ({ key, type, lng }) => {}, 
})

t`Hello ${'Username'}!`
// => Moin Username!
p`${1} tree`
// => 1 Baum
p`${5} tree`
// => 5 Bäume
mod(int)(5)
// => 50

API

The module exports 5 properties: t, p, mod, setConfig, getConfig

Methods

setConfig(config: ConfigObject): Promise<void>

The functions t, p & mod will use the new config after the returned Promise resolves. You don't need to set the whole config as setConfig will copy missing keys from the old or default config. You can also add new resources without commiting all old ones again.

In practice this means you can simply do:

// call setConfig to set resources and default language

//User wants to change UI language
await setConfig({ lng: 'de' })

to set a new language. If the resource for de is a function returning a promise it will call the function now and resolve as soon as the resource does.

To add resources after the first init just do:

await setConfig({
  resources: {
    'nl': <ResourceObject>
  }
})

It will keep all initinal resources and add the new one.

If the new one has the same key as an old one it will override it. This process will not keep your old translation, plural and modifier keys!

t`<String>`: String

t will calculate a key based on the provided string. All variables should be used using the ${} syntax.

Using this key it will lookup in the resource maps prioritized by the provided config.lng array. If some key in one resource map matches it will use the provided value by this key and insert the values to it.

To find the used key use onKey in config.

Example usage:

  t`Hallo` // => Hallo (if not defined in used resources)

p`<String>`: String

p will also calculate a key based on the provided string. Only one variable is accepted using ${} syntax. This variable should be count: Int. You can use this variable in your resource plural function to determine if it is plural or not.

Example usage:

setConfig({
  lng: ['en'],
  resources: {
    en: {
      plural: {
        <PluralKey>: (count: Int) => (count*10).toString()
      }
    }
  }
})

p`${5} drinks` // => '50', if PluralKey is matched

mod(<ModifierKey>): Function(...args): String

You can apply any modifier function from a resource to any value(s). Define which modifier to use from the resource using the ModifierKey. mod will return another function then.

You can provide as many arguments to the returned function as you want to. Your modifier defined in your resource then can handle the arguments.

Example usage:

setConfig({
  lng: ['en'],
  resources: {
    en: {
      modifier: {
        <ModifierKey>: (arg1, arg2) => (arg1 * arg2).toString()
      }
    }
  }
})

// mod(<ModifierKey>)(arg1, arg2)
mod(<ModifierKey>)(7, 5) // => 35

getConfig(): ConfigObject

that's it.

Objects

ConfigObject

A ConfigObject has a shape like this:

{
  lng: Array<ResourceId>,
  resources: {
    <ResourceId>: <ResourceObject>,
  },
  onKey: ({
    key: TranslationKey|PluralKey|ModifierKey, 
    type: 'translation'|'plural'|'modifier'|'unknown_translation'|'unknown_plural'|'unknown_modifier', 
    lng: ResourceId
  }) => void
}

ResourceObject

A ResourceObject contains the translation, plural & modifier key for a ResourceId. It looks like this:

{
  translation: {
    <TranslationKey>: <TranslationTemplate>
  },
  plural: {
    <PluralKey>: (count: Int) => String
  },
  modifier: {
    <ModifierKey>: (...args) => String
  }
}