Lesstep
Japanese sorting · gojūon order · Checked October 29, 2026

Japanese lists sorted in the wrong order

Japanese readers expect a list in gojūon order: the order of the kana syllabary, あいうえお かきくけこ, by how each word is read. JavaScript's sort() compares UTF-16 code units, so a Japanese list comes out in three blocks: words in hiragana, then words in katakana, then kanji in an order nobody reads them in. Intl.Collator("ja") puts kana in gojūon order, but it can't know how a kanji name is read. Keep each name's reading in kana, and sort by it:

const ja = new Intl.Collator("ja");

people.sort((a, b) =>
  ja.compare(a.yomi, b.yomi) ||
  ja.compare(a.name, b.name));

yomi is the reading, typed in kana when the record is made. Two people with the same reading are then ordered by the name.

Three sorts of the same names

Eight common Japanese family names, sorted three ways in Node.js 24 (ICU 78.3):

sort()CollatorBy reading
1伊藤伊藤伊藤 いとう
2佐藤高橋小林 こばやし
3小林佐藤佐藤 さとう
4山田山田鈴木 すずき
5渡辺小林高橋 たかはし
6田中田中田中 たなか
7鈴木渡辺山田 やまだ
8高橋鈴木渡辺 わたなべ

sort() follows the code points: 伊 is U+4F0A and 高 is U+9AD8. Intl.Collator("ja") follows CLDR's Japanese collation. It puts Latin letters first, then kana, then kanji, and it lists the kanji in a fixed order that begins 亜唖娃阿哀愛: the order of JIS X 0208, the Japanese character set, where each common kanji goes by one of its readings. 鈴 goes by レイ, so 鈴木 (すずき) comes last; 山 goes by サン, so 山田 (やまだ) comes before 田中 (たなか).

In kana, the collator is right. Its rules follow JIS X 4061, the Japanese standard for sorting, cited in a comment in the same file: あ and ア come together, and が right after か. Of nine words in kana, sort() put the five in hiragana first and the four in katakana after them, from いちご to りんご and again from アイス to ラッパ; the collator mixed them into one order.

Name the locale. a.localeCompare(b) with no locale uses the default of the machine it runs on, and with "en" the eight names came out in code-point order, as with sort().

Keep the reading

A kanji name doesn't say how it is read; 東 can be ひがし or あずま. Japanese sign-up forms ask for the name in kana (フリガナ, furigana) next to the name. Ask for it, store it, and sort by it; search by it too (readings are another index). It doesn't matter whether people type it in hiragana, katakana or half-width katakana: the collator ranks あいす, アイス and アイス together, and compared ア and ア as equal.

Headings あ か さ

A long Japanese list, such as a phone's contacts, is split under the first kana of each row of the syllabary: あ か さ た な は ま や ら わ. A user of Victoria, an Android launcher, asked for exactly that: A to Z, then あ to わ, then kanji with no reading (victoria-launcher #122).

const base = new Intl.Collator("ja",
  { sensitivity: "base" });
const HEADS = [
  ..."あかさたなはまやらわ"];
const KANA = /^[ぁ-ゖァ-ヺヲ-ン]/;

function rowOf(yomi) {
  if (!KANA.test(yomi)) return "";
  let row = "";
  for (const h of HEADS) {
    if (base.compare(h, yomi) <= 0)
      row = h;
  }
  return row;
}

rowOf("がっこう") is か, rowOf("データ") is た, and a reading that doesn't start with kana gets "", for a group of its own. sensitivity: "base" counts ぁ, が and ヴ as あ, か and う when it picks the row. We checked all 86 kana in hiragana and in katakana, alone and followed by more kana, and half-width forms, 357 cases: every one landed in its row.

In the database

SQLite compares text with memcmp() unless told otherwise, and COLLATE NOCASE folds only the 26 ASCII letters (its docs). In SQLite 3.53, ORDER BY name gave the same three blocks as sort(). That is audiobookshelf #5312, an audiobook server with over 14,000 stars on GitHub: titles and authors in Chinese, Japanese and Korean come out in no recognizable order because of NOCASE, and for Japanese the issue asks for gojūon order.

Sort in your app with Intl.Collator, or, in PostgreSQL, with an ICU collation, named with -x-icu after the language tag (its docs): ORDER BY yomi COLLATE "ja-x-icu". We did not run PostgreSQL for this page. Either way, order by the reading, not the name.

The rest of a Japanese check

A contact list with 鈴木 after 渡辺 looks broken to every Japanese user. The same pass catches Enter while typing Japanese (the fix), yen charged 100 times over (the fix), kanji drawn in their Chinese shapes (the fix), headings that break in the middle of a word (the fix), postal codes rejected when typed in Japanese (the fix), dates saved one day early in Japan (the fix), address forms in the American order (the fix), phone numbers sent to +81 with the 0 still in (the fix), PDFs with the Japanese missing (the fix), search that finds nothing in Japanese (the fix), previews cut down to “...” in Japanese (the fix), email subjects that arrive garbled (the fix), CSV files that open garbled in Excel (the fix), Japanese titles that give an empty URL slug (the fix), file names garbled on upload and download (the fix), dates in the Japanese era that come out wrong (the fix), full-width spaces that get past your checks (the fix), public holidays your app gets wrong (the fix), and vertical text that comes out sideways or upside down (the fix).

Lesstep translates web apps into Japanese and delivers them as one pull request. In Complete (US$249), we check every screen in Japanese, sorted lists included, and tell you where the order is wrong and which readings it needs. The first step is a free sample.

Unicode is a registered trademark of Unicode, Inc.; SQLite is a registered trademark of Hipp, Wyrick & Company, Inc.; PostgreSQL is a registered trademark of the PostgreSQL Community Association; Android is a trademark of Google LLC; Node.js is a trademark of the OpenJS Foundation. This page is not affiliated with or endorsed by any of them.

More: Enter sends the message while typing Japanese · Stripe charges 100 times too much in yen · Kanji in their Chinese shapes · Japanese headings that break in the middle of a word · Forms that reject numbers typed in Japanese · Dates that come out wrong for Japanese users · Address forms in the Japanese order · Japanese phone numbers in forms · Japanese text missing from your PDFs · Search that finds nothing in Japanese · Length limits that break in Japanese · Japanese email subjects that arrive garbled · Japanese CSV files that open garbled in Excel · Japanese titles that give an empty URL slug · Japanese file names garbled on upload and download · Japanese era dates that come out wrong · Full-width spaces that get past your checks · Japanese public holidays your app gets wrong · Japanese vertical text that comes out sideways or upside down · Japanese localization checklist · Japanese localization for your web app