Last two weeks I’ve been working hard on a first major release of jsLingui.

It all started with few independent tweets:

I began developing jsLingui because I wanted a simpler way to write an ICU MessageFormat. Type-checked, validated, high-level API which is converted to the MessageFormat. I had also other ideas with this lib, like compiling catalogs, but it didn’t seem important to me. However, the initial release had almost zero response and I moved to other project.

Browsing twitter search results I’ve found that a lot of people are looking for a lightweight alternative to react-intl. I quickly realised that my idea might be more important that I thought and start coding.

TL;DR: How big is this i18n lib?

About 6kb gzipped. Looking at webpack bundle visualizer, it’s actually smaller than redux.

Tradeoffs?

Most lightweight i18n libs are small only because they strip a lot of functionality, like plurals or date/number formatting. This isn’t the case.

jsLingui supports ICU MessageFormat, which means you can use anything you’re used to from react-intl — variable interpolation, plurals, genders and date/number formatting.

Small size of library is achieved using compiled message catalogs. The heavy lifting is done in compile time on local machine: Messages are parsed and compiled into pure function calls. Plural data are injected to message catalogs, so you always load only data you actually need.

Speaking about tradeoffs there’s usually inverse correlation between time and space complexity— if you make something fast, it takes a lot of memory. jsLingui is actually smaller and faster at the same time, because messages are parsed only in development. They are compiled into pure functions, so it’s blazingly fast in production.

API Changes

API is mostly the same. There are only few backward incompatible changes, all mentioned in migration guide. Few changes were made so the API is similar to react-intl for easier migration.

Components inside translations

jsLingui isn’t just an immature clone of react-intl. It’s also the first JS library, which has full support for inline components inside translations.

Components inside translations

Given example above, following message will be extracted: See all <0>unread messages</0> or <1>mark then</1> as read. This solution has several advantages:

translator gets the whole phrase, not chunks

all components are supported (not only built-in ones)

change of component props doesn’t require change of translations

As a former Djangonaut, I took this idea from Django and ported it to React environment.

Handy CLI

Command line interface was part of jsLingui from the very first releases. However, it’s getting more and more important. You can use it now for extracting and compiling message catalogs. No need to write them manually.

There’s also ongoing work on integration with translation management services like Transifex.

extracting messages from source files

New documentation

Starting from this release, the official documentation is hosted at GitBook. It unifies scattered READMEs and pages from Wiki.

Challenges

Right now the biggest challenge is make this library work with frameworks like Create React App or Neutrino, where you don’t have much freedom to edit babel config. If you want to use high-level API for writing messages, you need a babel preset.

You still can use this library even without babel preset, but you’re forced to use only low-level API and then it’s almost like using react-intl itself (except smaller and faster).

What’s next

I want to pursue minimal bundle size to the limits, so the next challenging feature is support of code-splitting. Ideally, messages should be extracted from each chunk separately and loaded along with the chunk. There’re many obstacles to make this work, but it’s something I want to focus next.

Give it a try

If you want to try it, even just for few components, it’s really very easy. Look at this comparison of original component and translated one to see the difference:

Seamless translation in React

There’s a tutorial for React applications.

Interested in this library? Ping me on twitter or write a comment. I’m happy for any feedback.