File formats & standardsこの記事を日本語で読む

ICU MessageFormat: writing strings that handle plurals and gender correctly

A string like "You have 1 items" is a grammar bug, not a typo, and it exists because most codebases handle plurals by hardcoding English's two-form rule ("1" vs "not 1") directly into the string template. That rule is specific to English; other languages have more forms, fewer meaningful distinctions, or forms selected by criteria other than raw count.

ICU MessageFormat is a syntax, defined as part of the ICU (International Components for Unicode) project, for writing a single message template that branches correctly per language — plural, gender, and other variants included — without hardcoding any language's grammar into the surrounding code.

Arguments: the basic substitution

At its simplest, MessageFormat is just named placeholders in braces, substituted with a runtime value. This part is unremarkable and works like any other templating syntax.

{playerName} defeated {enemyName}.

plural: branching on CLDR categories, not raw numbers

The plural argument type does not branch on the literal number — it branches on the CLDR plural category that number maps to in the target language. CLDR (Unicode Common Locale Data Repository) defines up to six categories per language — zero, one, two, few, many, other — and which categories a given language actually uses, and by which rule, is data, not something the message author decides.

Inside each branch, # is replaced with the actual number, so the branch text stays readable while the number itself is inserted automatically.

{count, plural,
  one {# item found}
  other {# items found}
}

select: branching on an arbitrary category, most often gender

select is the general-purpose branching form: it matches an argument's value against named cases, with other as the required fallback. The most common use is grammatical gender, where a sentence's verb form or pronoun depends on the subject's gender and English has no equivalent distinction to fall back on.

{gender, select,
  male {He picked up the sword.}
  female {She picked up the sword.}
  other {They picked up the sword.}
}

selectordinal: for 1st, 2nd, 3rd — not how many, but which one

selectordinal looks like plural but selects an ordinal category instead of a cardinal one — the difference between "3 items" (cardinal) and "3rd place" (ordinal). English happens to need three ordinal forms (one, two, few, mapping to -st, -nd, -rd) plus other for everything else; the categories and their meaning again come from CLDR, not from the message author's assumptions.

{rank, selectordinal,
  one {#st place}
  two {#nd place}
  few {#rd place}
  other {#th place}
}

Nesting and offset

Message arguments can nest inside one another — a select branch can contain a plural, a plural branch can contain another select — which is how a single message correctly handles both gender and count at once. Nesting is also where MessageFormat becomes hard to translate: a translator working inside a deeply nested block has to track which combination of conditions produced the text they are looking at, and a mistake in one branch is easy to miss during review.

The offset feature on plural subtracts a fixed number before category selection, useful for phrasing like "you and 2 others" where the displayed count and the count driving the language rule differ by a constant.

{count, plural, offset:1
  =0 {no one else}
  one {you and # other}
  other {you and # others}
}

Why the risk is real, not theoretical

ICU MessageFormat exists because plural and gender rules genuinely vary by language and cannot be inferred from English source text. That same power is the format's main risk: a message with two levels of nesting is difficult for a translator to read correctly, easy to break with a missing closing brace, and hard for a reviewer to verify without running it through every branch. Keeping individual messages as flat as the grammar allows, and reserving nesting for cases that truly need it, is worth treating as a deliberate constraint rather than an afterthought.

Related articles