@messageformat/core vs format-message vs intl-messageformat
Internationalization Message Formatting Libraries
@messageformat/coreformat-messageintl-messageformatSimilar Packages:

Internationalization Message Formatting Libraries

@messageformat/core, format-message, and intl-messageformat are JavaScript libraries designed to handle dynamic text interpolation, pluralization, and select logic using the ICU MessageFormat syntax. They enable developers to write translation strings that adapt to different languages and contexts without hard-coding logic. While they share a common goal, they differ in compilation strategy, runtime dependencies, and ecosystem support. intl-messageformat is the most widely adopted in modern React ecosystems, @messageformat/core serves as a low-level compiler for custom tools, and format-message offers a standalone alternative with a simpler API.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
@messageformat/core01,766302 kB172 years agoMIT
format-message020641.4 kB28-MIT
intl-messageformat014,743113 kB62 days agoBSD-3-Clause

Internationalization Message Formatting: Runtime vs Compiler

All three libraries solve the same core problem — turning static translation strings into dynamic, language-aware text. They support the ICU MessageFormat standard, which handles plurals, gender selection, and variable interpolation. However, they approach the task differently in terms of compilation, dependencies, and ecosystem fit. Let's break down how they work in real engineering scenarios.

🛠️ Compilation Strategy: Build-Time vs Runtime

How and when the message string turns into executable code matters for performance and bundle size.

intl-messageformat compiles messages at runtime by default.

  • You pass the string to the constructor, and it parses it when the app loads.
  • You can precompile messages to functions to save runtime cost, but the default is runtime parsing.
// intl-messageformat: Runtime compilation
import IntlMessageFormat from 'intl-messageformat';

const msg = new IntlMessageFormat('Hello {name}', 'en-US');
const output = msg.format({ name: 'Alice' });

@messageformat/core is a compiler only.

  • It does not format text directly.
  • You run it during your build process to turn strings into JavaScript functions.
  • The output function has no dependencies.
// @messageformat/core: Build-time compilation
import MessageFormat from '@messageformat/core';

const mf = new MessageFormat('en-US');
const comp = mf.compile('Hello {name}');
// `comp` is a standalone function you can ship
const output = comp({ name: 'Alice' });

format-message supports both runtime and build-time.

  • You can call the function directly with a string.
  • It also offers a CLI to precompile messages into code.
  • Flexible for mixed workflows.
// format-message: Runtime usage
import formatMessage from 'format-message';

const output = formatMessage('Hello {name}', { name: 'Alice' }, 'en-US');

📦 Runtime Dependencies and Polyfills

Dependency management affects bundle size and browser support.

intl-messageformat relies on the native Intl API.

  • Modern browsers support this out of the box.
  • Older browsers (like Internet Explorer) need polyfills.
  • The FormatJS ecosystem provides these polyfills explicitly.
// intl-messageformat: Requires Intl polyfill for old browsers
// import '@formatjs/intl-pluralrules/polyfill';
// import '@formatjs/intl-numberformat/polyfill';

const msg = new IntlMessageFormat('You have {count} items', 'en-US');

@messageformat/core generates dependency-free code.

  • The compiled function does not need Intl.
  • It implements logic using plain JavaScript.
  • Great for environments where polyfills are hard to manage.
// @messageformat/core: No Intl dependency in output
const mf = new MessageFormat('en-US');
const comp = mf.compile('You have {count} items');
// Compiled code handles plural logic internally

format-message also depends on Intl for some features.

  • It tries to use native APIs when available.
  • May require polyfills for full ICU support in older environments.
  • Similar profile to intl-messageformat but less integrated tooling.
// format-message: Intl dependent for plurals
formatMessage.setup({ locale: 'en-US' });
const output = formatMessage('You have {count, plural, one {item} other {items}}', { count: 5 });

🧩 API Design and Developer Experience

The way you call these libraries impacts code readability and maintenance.

intl-messageformat uses a class-based API.

  • You create an instance per message or cache instances.
  • Clear separation between definition and formatting.
  • Strong TypeScript types available.
// intl-messageformat: Class instance
const msg = new IntlMessageFormat('Welcome {user}', 'en-US');
console.log(msg.format({ user: 'Bob' }));

@messageformat/core uses a compiler-function flow.

  • You compile once, then call the result many times.
  • Feels more like a build tool than a runtime library.
  • Less boilerplate in the final bundled code.
// @messageformat/core: Compile then call
const mf = new MessageFormat('en-US');
const renderWelcome = mf.compile('Welcome {user}');
console.log(renderWelcome({ user: 'Bob' }));

format-message uses a functional API.

  • Single function call handles everything.
  • Very concise for simple scripts.
  • Can feel less structured in large applications.
// format-message: Single function call
console.log(formatMessage('Welcome {user}', { user: 'Bob' }, 'en-US'));

🌍 Ecosystem and Maintenance

Long-term support matters for enterprise applications.

intl-messageformat is part of the FormatJS ecosystem.

  • Maintained by a large team and community.
  • Integrates deeply with React, Next.js, and GraphQL tools.
  • Regular updates and security patches.

@messageformat/core is part of the messageformat project.

  • Actively maintained but focused on the compiler layer.
  • Often used under the hood by other tools.
  • Stable API with fewer breaking changes.

format-message has lower recent activity.

  • Still functional but less community momentum.
  • Fewer integrations with modern frameworks.
  • Suitable for stable, low-change projects.

📊 Summary: Key Differences

Featureintl-messageformat@messageformat/coreformat-message
Primary UseRuntime formatting in appsBuild-time compilationRuntime or CLI
DependenciesNeeds Intl polyfillsNone in outputNeeds Intl polyfills
API StyleClass-basedCompiler + FunctionFunctional
EcosystemLarge (FormatJS)Medium (Tooling)Smaller
Best ForReact/Modern Web AppsCustom i18n ToolsSimple Scripts

💡 The Big Picture

intl-messageformat is the safe bet for most teams. It offers the best balance of features, support, and integration with modern frameworks. If you are building a React app, this is likely what you want.

@messageformat/core is for tool builders. If you are creating your own i18n platform or need to ship zero-dependency code, this gives you the engine without the overhead.

format-message is a viable alternative for simpler needs. It works well if you want ICU support without buying into the FormatJS ecosystem, but check maintenance status before committing to large projects.

Final Thought: All three handle ICU syntax correctly. The choice depends on whether you need a full ecosystem (intl-messageformat), a compiler engine (@messageformat/core), or a lightweight standalone tool (format-message).

How to Choose: @messageformat/core vs format-message vs intl-messageformat

  • @messageformat/core:

    Choose @messageformat/core if you are building your own internationalization tooling or need a compiler that generates standalone JavaScript functions without runtime dependencies. It is ideal for build-time compilation pipelines where you want to ship zero-dependency formatting code to the browser. Avoid using it directly in application code if you need a ready-made formatting API.

  • format-message:

    Choose format-message if you need a lightweight, standalone library that supports ICU syntax without the overhead of the larger FormatJS ecosystem. It is suitable for smaller projects or non-React environments where simplicity is key. However, verify current maintenance status before committing, as community activity is lower compared to alternatives.

  • intl-messageformat:

    Choose intl-messageformat if you are building a modern web application, especially with React, and need robust support for the Intl API, polyfills, and a large ecosystem. It is the standard choice for projects requiring long-term maintenance, strong TypeScript support, and integration with tools like react-intl or next-intl.

README for @messageformat/core

messageformat

The experience and subtlety of your program's text is important. The messageformat project provides a complete set of tools for handling all the messages of your application, for both front-end and back-end environments; for both runtime and build-time use. It's built around the ICU MessageFormat standard and supports all the languages included in the Unicode CLDR, but it can be just as useful if you're dealing with only one of them.

ICU MessageFormat is a mechanism for handling both pluralization and gender in your applications. This is the core compiler of a JavaScript project supports and extends all parts of the official Java/C++ implementation, with the exception of the deprecated ChoiceFormat. In addition to compiling messages into JavaScript functions, it also provides tooling for making their use easy during both the build and runtime of your site or application.

For more details, please see the project's documentation site: http://messageformat.github.io/

This package was previously named messageformat.


Messageformat is an OpenJS Foundation project, and we follow its Code of Conduct.

Copyright OpenJS Foundation and messageformat contributors. All rights reserved. The OpenJS Foundation has registered trademarks and uses trademarks. For a list of trademarks of the OpenJS Foundation, please see our Trademark Policy and Trademark List. Trademarks and logos not indicated on the list of OpenJS Foundation trademarks are trademarks™ or registered® trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.

Browser testing provided by:

BrowserStack