format-message vs intl-messageformat vs messageformat vs react-intl
Internationalization Libraries for JavaScript
format-messageintl-messageformatmessageformatreact-intlSimilar Packages:

Internationalization Libraries for JavaScript

Internationalization (i18n) libraries are essential tools in web development that help developers create applications that can be easily adapted to various languages and regions. These libraries provide functionalities for formatting messages, handling pluralization, and managing locale-specific data, enabling a seamless user experience across different cultures. They are crucial for applications targeting global audiences, ensuring that content is not only translated but also culturally relevant and contextually appropriate.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
format-message020641.4 kB28-MIT
intl-messageformat0-113 kB-8 days agoBSD-3-Clause
messageformat01,763172 kB167 months agoApache-2.0
react-intl0-179 kB-8 days agoBSD-3-Clause

Feature Comparison: format-message vs intl-messageformat vs messageformat vs react-intl

Message Formatting

  • format-message:

    format-message provides a straightforward API for formatting strings with placeholders, making it easy to interpolate variables into messages. It supports basic pluralization and is designed for simplicity, allowing developers to quickly implement localization without complex configurations.

  • intl-messageformat:

    intl-messageformat excels in handling complex message formatting scenarios, including pluralization and gender variations. It uses ICU message syntax, which allows for rich message definitions and is particularly useful for applications with diverse localization requirements.

  • messageformat:

    messageformat offers a flexible approach to message formatting, allowing developers to define custom message structures and syntax. It is particularly useful for applications that require a high degree of customization in how messages are formatted and displayed.

  • react-intl:

    react-intl provides built-in components for formatting messages, dates, and numbers in a React application. It leverages the capabilities of intl-messageformat under the hood, making it easy to manage localization within React components.

Localization Support

  • format-message:

    format-message focuses on providing essential localization features, making it suitable for applications that require basic localization without extensive configuration. It supports locale-specific formatting but may lack advanced features found in other libraries.

  • intl-messageformat:

    intl-messageformat is designed for comprehensive localization support, allowing developers to create messages that adapt to different languages and regions. Its support for ICU message syntax makes it a powerful choice for applications with complex localization needs.

  • messageformat:

    messageformat offers flexibility in localization, allowing developers to define their own message structures. However, it may require more effort to implement compared to libraries with built-in localization features.

  • react-intl:

    react-intl provides extensive localization support tailored for React applications, including easy integration with React components. It simplifies the process of managing translations and locale-specific formatting, making it a robust choice for internationalized React apps.

Integration with Frameworks

  • format-message:

    format-message can be easily integrated into various JavaScript frameworks, but it does not provide specific components for any framework, making it a more generic solution for message formatting.

  • intl-messageformat:

    intl-messageformat is a standalone library that can be used across different frameworks, but it requires additional setup for integration. It is framework-agnostic, making it versatile for various applications.

  • messageformat:

    messageformat is also framework-agnostic and can be integrated into any JavaScript application. However, it does not provide specific components for popular frameworks, requiring developers to handle integration manually.

  • react-intl:

    react-intl is specifically designed for React applications, providing components and hooks that make it easy to integrate localization directly into the React component tree. This tight integration enhances the developer experience and streamlines localization efforts.

Learning Curve

  • format-message:

    format-message has a low learning curve, making it accessible for developers who are new to internationalization. Its straightforward API allows for quick implementation without extensive documentation.

  • intl-messageformat:

    intl-messageformat has a moderate learning curve due to its use of ICU message syntax, which may require some time for developers to become familiar with. However, its powerful features justify the investment in learning.

  • messageformat:

    messageformat may have a steeper learning curve compared to simpler libraries, as it allows for a high degree of customization in message formatting. Developers may need to spend time understanding its syntax and capabilities.

  • react-intl:

    react-intl is relatively easy to learn for developers familiar with React, as it provides a familiar component-based approach. The documentation is comprehensive, helping new users quickly understand how to implement localization in their applications.

Community and Ecosystem

  • format-message:

    format-message has a growing community, but it may not have as extensive an ecosystem as some of the larger libraries. It is suitable for projects that prioritize simplicity and lightweight solutions.

  • intl-messageformat:

    intl-messageformat benefits from a strong community and is widely used in various applications. Its compatibility with ICU syntax makes it a preferred choice for developers looking for robust localization features.

  • messageformat:

    messageformat has a smaller community compared to other libraries, but it offers unique features that cater to specific needs. It is ideal for projects that require custom message formatting capabilities.

  • react-intl:

    react-intl has a large and active community, being part of the FormatJS ecosystem. It is well-maintained and frequently updated, providing a wealth of resources and support for developers working on React applications.

How to Choose: format-message vs intl-messageformat vs messageformat vs react-intl

  • format-message:

    Choose format-message for its simplicity and ease of use, especially if you need a lightweight solution for formatting messages with variable interpolation and pluralization without the overhead of a full i18n framework.

  • intl-messageformat:

    Select intl-messageformat if you require advanced message formatting capabilities, including support for complex pluralization and gender-based variations, making it suitable for applications with intricate localization needs.

  • messageformat:

    Opt for messageformat if you need a library focused on message formatting with a strong emphasis on syntax and flexibility, allowing for a more customizable approach to handling translations and message structures.

  • react-intl:

    Use react-intl if you are building a React application and want a comprehensive solution that integrates seamlessly with React components, providing built-in support for formatting dates, numbers, and strings according to locale.

README for format-message

format-message

Internationalize text, numbers, and dates using ICU Message Format

npm Version Build Status JS Standard Style MIT License

Quick Examples

npm install format-message --save

By default, the passed in string is parsed and formatted.

var formatMessage = require('format-message')
var message = formatMessage('Hello { place }!', { place: 'World' })

You can pass an object to provide more information about a message.

import formatMessage from 'format-message'

let message = formatMessage({
  id: 'welcome_name', // optional, can be generated from `default`
  default: 'Welcome, {name}!',
  // optional description gives translators more context
  description: 'Greeting at the top of the home page, showing the current user’s preferred name'
}, {
  name: user.preferredName
})

Configure format-message to use translations, infer missing ids from the default message, report and replace missing translations, and add custom placeholder style formats.

formatMessage.setup({
  locale: 'es-ES', // what locale strings should be displayed
  translations: require('./locales'), // object containing translations
  generateId: require('format-message-generate-id/underscored_crc32'), // function to generate a missing id from the default message
  missingReplacement: '!!NOT TRANSLATED!!', // use this when a translation is missing instead of the default message
  missingTranslation: 'ignore', // don't console.warn or throw an error when a translation is missing
  formats: {
    number: { // add '{ amount, number, EUR }' format
      EUR: { style: 'currency', currency: 'EUR' }
    },
    date: { // add '{ day, date, weekday }' format
      weekday: { weekday: 'long' }
    }
  }
})

Formatting number, date, and time arguments relies on the ECMAScript Internationalization API (Intl). If you are in an environment missing this API (like node <= 0.12, IE < 11, or Safari < 10) you'll want to use a polyfill. Otherwise an error will be thrown when trying to format these arguments.

Format Overview

The ICU Message Format is a great format for user-visible strings, and includes simple placeholders, number and date placeholders, and selecting among submessages for gender and plural arguments. The format is used in apis in C++, PHP, and Java. There is a guide for translators you can send to your translators, and it's a nice primer for developers as well.

format-message provides a way to write your default (often English) message patterns as literals in your source, and then lookup translations at runtime. There are also tools to lint, extract, and inline translations.

This relies on message-format for parsing and formatting ICU messages.

Supported ICU Formats

See message-format for supported ICU formats.

Quoting escaping rules

See the ICU site and message-format for details on how to escape special characters in your messages.

Loading locale data

format-message supports plurals for all CLDR languages. Locale-aware formatting of number, date, and time are delegated to the Intl apis, and select is the same across all locales. You don't need to load any extra files for particular locales for format-message itself.

API

formatMessage(pattern[, args[, locales]])

Translate and format the message with the given pattern and arguments. Literal arguments for pattern and locales are recommended so you can take advantage of linting, extraction, and inlining tools.

Parameters

  • pattern is a string or object describing the message. A string value is equivalent to { default: value }.
    • default is a properly formatted ICU Message Format pattern. A poorly formatted pattern will cause an Error to be thrown.
      • This will be used directly if no translations are conifgured or if the translation is missing and no missingReplacement is configured.
      • This is also used to generate an inferred id, if none is explicitly included.
    • id is a string identifier for the message. This is used as a key to look up the translation from the configured translations. If none is specified, one is generated from the default pattern.
    • description is a string providing additional context for this message. This has no runtime effect, but can be extracted along with the default message to be sent to translators.
  • args is an object containing the values to replace placeholders with. Required if the pattern contains placeholders.
  • locales is an optional string with a BCP 47 language tag, or an array of such strings.
    • When specified, format-message will attempt to look up the translation for each language until one is found.
    • When omitted the locale configured in setup() is used instead.

formatMessage.rich(pattern[, args[, locales]])

Translate and format the message with the given pattern and arguments and return an array of message parts. If the pattern contains any html-like tags (<a>go</a>, <icon/>, etc.) they are interpreted as placeholders expecting a function that will receive the children message parts as an array. Attributes are not supported for the placeholder tags and will throw a parse error.

Note that for React, and perhaps other libraries as well, elements in an array should have a key specified, or you will trigger warnings.

formatMessage.rich("Click <a>here<a/>", {
  a: ({ children }) => <Link key="a">{children}</Link>
})
// returns [ "Click ", <Link key="a">here</Link> ]

Parameters

The same as formatMessage(pattern[, args[, locales]]).

formatMessage.setup(options)

Configure formatMessage behavior for subsequent calls. This should be called before any code that uses formatMessage. Returns an object containing the current options.

Parameters

  • options is an object containing the following config values:
    • locale is the default locale to use when no locale is passed to formatMessage. Defaults to "en".
    • translations is an object with locales as properties, each value is an object with message ids as properties. The value for each message id property is either the translated message pattern string, or an object with the message property containing the translated message pattern string.
    • generateId(defaultPattern) is a function to generate an id from the default message pattern.
      • defaultPattern is the default message pattern.
      • This function must return a string id.
      • The format-message-generate-id module has a few functions you can use if you don't want to use your own.
    • missingReplacement is a string or function that returns a string that will be used when a message translation isn't found. If a function, it will be called with (pattern, id, locale) parameters to get the replacement. If null or not specified, then the default message is used.
    • missingTranslation is one of "ignore", "warning", "error". By default it is "warning", and missing translations cause a console warning. If "error", an error is thrown.
    • formats is an object containing objects that define placeholder styles { name, type, style }:
      • number is an object containing number format styles to add. Each property name can be used afterwards as a style name for a number placeholder. The value of each property is an object that will be passed to an Intl.NumberFormat constructor as the second argument.
      • date is an object containing date format styles to add. Each property name can be used afterwards as a style name for a date placeholder. The value of each property is an object that will be passed to an Intl.DateTimeFormat constructor as the second argument.
      • time is an object containing time format styles to add. Each property name can be used afterwards as a style name for a time placeholder. The value of each property is an object that will be passed to an Intl.DateTimeFormat constructor as the second argument.

formatMessage.namespace()

Return a new instance of formatMessage with isolated configuration. Calls to setup() on the new namespace will not be affect any another namespace (including the global namespace).

var namespace = formatMessage.namespace()

formatMessage.setup({
  locale: "en",
  translations: {
    en: {
      foo: "foo"
    }
  }
})

namespace.setup({
  locale: "fr",
  transations: {
    fr: {
      foo: "bar"
    }
  }
})

formatMessage("foo") // => "foo"
namespace("foo") // => "bar"

If you are using a custom namespace and still want to be able to extract strings using the format message CLI, create a module named format-message.js that exports the new namespace. Import formatMessage from this module in all other modules that use the namespace.

Localization apis

format-message also provides a few extra functions to simplify localizing (but not translating) data. These mostly just pass through to Intl APIs.

import { number, date, time, select, plural, selectordinal } from 'format-message'
// or
var { number, date, time, select, plural, selectordinal } = require('format-message')

number(value [, style [, locale ]])

Convert a number to a localized string.

Parameters

  • value is the number to format.
  • style is the optional string name of a style (decimal, integer, percent, etc). Defaults to 'decimal'.
  • locale is the optional BCP 47 language tag. If not passed, the locale passed to setup() will be used.

date(value [, style [, locale ]])

Convert a date to a localized date string.

Parameters

  • value is the date to format.
  • style is the optional string name of a style (short, medium, long, full, etc). Defaults to 'medium'.
  • locale is the optional BCP 47 language tag. If not passed, the locale passed to setup() will be used.

time(value [, style [, locale ]])

Convert a date to a localized time string.

Parameters

  • value is the date to format.
  • style is the optional string name of a style (short, medium, long, full, etc). Defaults to 'medium'.
  • locale is the optional BCP 47 language tag. If not passed, the locale passed to setup() will be used.

select(value, options)

Select an option by exact text match. (This is not locale-specific.)

Parameters

  • value is the string to match.
  • options is an object whose keys are candidates for matching value. The value of the property with the matching key is returned, or the other property's value. The object should always have an other property.

plural(value [, offset ], options [, locale ]) and selectordinal(value [, offset ], options [, locale ])

Select an option by matching plural rules. plural matches rules for cardinal numbers, and selectordinal matches rules for ordinal numbers. These function very similar to the parameters plural and selectordinal embedded in a message.

Parameters

  • value is the number to match against plural rules.
  • offset is an optional number subtracted from value before matching keyword plural rules. The offset is not applied when matching exact number options.
  • options is an object whose keys are candidates for matching value. The value of the property with the matching key is returned, or the other property's value. The object should always have an other property. Keys should be either plural keywords (zero, one, two, few, many, other), or exact number matches (=13, =4, etc). Note that not all languages use all rules. For example English doesn't have a zero rule (0 falls under the other rule), but can still match =0.

format-message/react

Deprecated: Use formatMessage.rich() instead. This module includes utilities for working specifically with react when composing messages with embedded components.

formatChildren(message, elements)

Applies a message to a map of React elements to produce a list of child nodes.

Parameters

  • message is a pre-formatted string containing tokens marking the beginning and ending of nodes.
  • elements is an object with keys matching tokens in the message, and values of React elements to put message parts in.

Example

import formatMessage from 'format-message'
import {formatChildren} from 'format-message/react'

export default ({ extensions }) =>
  <div title={formatMessage('Choose a file')}>
    {formatChildren(
      formatMessage('Drag & Drop {extensions} files here <0>or</0> <1>Browse</1>', {
        extensions
      }),
      [
        <span className="or" />,
        <span className="browse" />
      ]
    )}
  </div>

produces the same tree as

<div title="something">
  Drag & Drop {extensions} files here
  <span className="or">or</span>
  <span className="browse">
    Browse
  </span>
</div>

You can also provide an Object and use tag names that match the object's property names

import formatMessage from 'format-message'
import {formatChildren} from 'format-message/react'

export default ({ extensions }) =>
  <div title={formatMessage('Choose a file')}>
    {formatChildren(
      formatMessage('Drag & Drop {extensions} files here <span1>or</span1> <span2>Browse</span2>', {
        extensions
      }),
      {
        span1: <span className="or" />,
        span2: <span className="browse" />
      }
    )}
  </div>

To be valid, a tag name can include any character except <, /, >, and whitespace characters.

format-message/inferno

Deprecated: Use formatMessage.rich() instead. This module includes utilities for working specifically with Inferno when composing messages with embedded components. The API is identical to format-message/react, only it works with Inferno vdom nodes instead of React elements.

formatChildren(message, elements)

Applies a message to a map of vdom nodes to produce a list of child nodes.

Parameters

  • message is a pre-formatted string containing tokens marking the beginning and ending of nodes.
  • elements is an object with keys matching tokens in the message, and values of vdom elements to put message parts in.

Example Messages

The examples provide sample output. Some assume you have configured with translations.

Simple messages with no placeholders

formatMessage('My Collections')
// "Minhas Coleções"

Simple string placeholders

formatMessage('Welcome, {name}!', { name: 'Bob' })
// "Bem Vindo, Bob!"

String placeholders with nested data

formatMessage('Welcome, {people.wes.name}, {people.julie.name}, and {people.sharon.name}!', {
	people: {
		wes: {
			name: 'Wes Phillips'
		},
		julie: {
			name: 'Julie Roberts'
		},
		sharon: {
			name: 'Sharon Sanders'
		}
	}
})
// "Welcome, Wes Phillips, Julie Roberts, and Sharon Sanders!"

Complex number, date, and time placeholders

formatMessage('{ n, number, percent }', { n: 0.1 })
// or preferred since there is no text to translate:
number(0.1, 'percent')
// "10%"

formatMessage('{ shorty, date, short }', { shorty: new Date() })
// or preferred since there is no text to translate:
date(new Date(), 'short')
// "1/1/15"

formatMessage('You took {n,number} pictures since {d,date} {d,time}', { n: 4000, d: new Date() })
// "You took 4,000 pictures since Jan 1, 2015 9:33:04 AM"

Complex string with select and plural in ES6

import formatMessage from 'format-message'

// using a template string for multiline, NOT for interpolation
formatMessage(`On { date, date, short } {name} ate {
  numBananas, plural,
       =0 {no bananas}
       =1 {a banana}
       =2 {a pair of bananas}
    other {# bananas}
  } {
  gender, select,
      male {at his house.}
    female {at her house.}
     other {at their house.}
  }`, {
  date: new Date(),
  name: 'Curious George',
  gender: 'male',
  numBananas: 27
})
// "On 1/1/15 Curious George ate 27 bananas at his house."

License

This software is free to use under the MIT license. See the LICENSE-MIT file for license text and copyright information.