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

etty

v0.2.0

Published

Library that provides typed translations system without pain for multilanguage websites using typescript and mobx

Readme

Easy Typed Translations? Yes!

This lightweight package allows you to create MobX-based store for translations and easily manage it. Etty is developed using TypeScript and created for using mainly in React projects. But because of there is no any dependence of React, it can be suitable with any frontend-framework (but this is not verified).


Usage

  1. Install package
npm install etty
  1. Create a translation template (e.g. src/config/template.json)
{
    "myAwesomeTranslation": {
        "field_1": "",
        "field_2": ""
    },
    "myTranslationArray": ["", "", ""]
}
  1. Create a store based on it
import Etty from "etty"
import * as template from "config/template.json"

export type Translation = typeof template
export default new Etty<Translation>()
  1. Enjoy your observable translations with full autocomplete! Etty Screenshot 1

Properties

EttyStore.init()

Initializes the Etty store. Without this initialization any attempt to acces to EttyStore.$ will throw and error. Suggested to be called in componentDidMount() of your React application's App component. For example:

import * as React from "react"
import { observer } from "mobx-react"
import EttyStore, { Translation } from "stores/EttyStore"
import Superagent from "superagent"

@observer
export default class Application extends React.Component {
    state = {
        initialError: false
    }

    componentDidMount() {
        var userLocale = navigator.userAgent.language
        var locales = ["en-US", "en-GB", "ru"]
        EttyStore.init({
            locales,
            initialLocale: locales.includes(userLocale)
                ? userLocale
                : locales[0],
            fetch: (locale: string) => {
                return new Promise<Translation>((resolve, reject) => {
                    Superagent.get(`/api/translate/${locale}`).then(resp => {
                        resolve(resp.body) 
                    }).catch(reject)
                })
            }
        }).catch(() => {
            this.setState({ initialError: true })
        })
    }

    render() {
        if (this.state.initialError)
            return "Whoops! Sorry, we are failed to initialize the application"

        return !EttyStore.ready
            ? // Etty is fetching initial locale translations yet
            "Prepairing application..."
            : // Etty is ready now and available anywhere it imported! Do your stuff here
            EttyStore.$.helloWorld
    }
}

@params

props: EttyProps

name | type | required | default value | description ---- | ---- | -------- | ------------- | ----------- EttyProps.delay | number | no | 0 | A minimal delay in milliseconds before the translation request will be considered as successful. For example, if you wil specify 600, then any translation request within EttyStore will take at least 600 millisections unless it fails. EttyProps.locales | string[] | yes | - | A list of available locales, e.g. ["ru", "en", "uk"] EttyProps.initialLocale | string | yes | - | An initial locale. EttyStore.init will load a translation for this locale. EttyProps.fetch | (locale: string) => Promise<T> | yes | - | A function, where you can make request for the translation for locale that is passed as parameter. Should return Promise that contains data of type T (this type you are passing when creating an instance: new Etty<SomeTranslationType>(), so T is SomeTranslationType here) EttyProps.onFetchError | (error?: any) => void | no | () => {} | A function that is being called each time when the EttyProps.fetch() will throw Promise.catch. Does not being called, if EttyStore.init() throws Promise.catch (use it's catch to handle initialization fail manually).

@returns

A Promise.

EttyStore.ready: boolean

@observable
Used as flag that shows, does the EttyStore ready for usage or not. Consider not to render your application (at least, do not use EttyStore.$) until this field became true.

EttyStore.locale: string

@observable
Current locale of the store. Can reffer both loaded locale and loading locale.

EttyStore.locales: string[]

A plain JS array of locales that was passed to EttyStore.init.

EttyStore.isTranslating: boolean

@computed
Returns true if translation for EttyStore.locale is now loading and false if it's ok and translation for EttyStore.locale is already loaded.

EttyStore.loadedLocale: string

@computed
Returns safe locale, i.e. the last used locale for which the translation already exist. During EttyStore.isTranslating is true, this property does not equals EttyStore.locale. Use it everywhere you need to use current locale of the language (e.g. some translatable fields in your API response, etc). The translation that is returned in EttyStore.$ uses locale that specified in EttyStore.loadedLocale.

EttyStore.loadTranslation()

Use this function when you want to change locale. For example:

import * as React from "react"
import { observer } from "mobx-react"
import EttyStore from "stores/EttyStore"

@observer
export default class LocaleSwitch extends React.Component {
    handleClick = (locale: string) => {
        if (!EttyStore.isTranslating)
            EttyStore.loadTranslation(locale)
    }

    render() {
        return (
            <div className="c-locale-switch">
                {EttyStore.locales.map(locale => (
                    <button
                        key={locale}
                        onClick={() => this.handleClick(locale)}
                        className={`locale ${locale == EttyStore.loadedLocale ? "active" : ""}`}
                    >{locale}</button>
                ))}
            </div>
        )
    }
}

@params

locale: string - a locale for which the translation should be loaded and shown.

@returns

boolean. If the translation for specified locale has already been loaded, then this method just changes the EttyStore.locale and returns false (means: "No, I'm not loading anything!"). Otherwise changes the EttyStore.locale, starts to load the translation (the flag EttyStore.isTranslating became true) and returns true (means: "Yes, sir, I'm loading the translation!")

EttyStore.$: T

@computed
Returns the translation object of type that was specified during construction (e.g. if you used new Etty<MyTranslationType>(), then EttyStore.$ will return object of type MyTranslationType). Uses translation for locale specified in EttyStore.loadedLocale, so once EttyStore initialized, you can consider that this field is safe for work. Throws an error if EttyStore is not initialized


Other fields

Fields that are not described in the section above should be considered as private and should not be used.


Generate translation JSONs based on template

There is an etty-mockup that was created exactly for this purpose!
You may also be interested in automated translation files generating via Webpack. I have developed the etty-webpack-plugin for this purpose.

Real-life example

Now is developing at etty-example repo. Some things are already done, so visit it to get more clearly how this library works.

Contributing

Feel free to leave issues, feature and pull requests. Any help that will make Etty better is highly appreciated!