Skip to content

PinyinJS

PinyinJS converts Chinese hanzi to pinyin, in TypeScript, in Node and the browser. It also parses, validates and writes pinyin syllables on their own, with no dictionary.

Terminal window
pnpm add @kensio/pinyinjs

Node 24+, or any browser. The core imports no Node built-ins.

Converting needs a dictionary, and it is a fetchable file rather than a JavaScript module, so loading it is asynchronous. Load it once and keep it: it is immutable and safe to share.

import { convert, loadDictionary } from "@kensio/pinyinjs";
import { fileSource } from "@kensio/pinyinjs/node";
const source = fileSource("node_modules/@kensio/pinyinjs/data");
const dictionary = await loadDictionary(source, "full");
convert(dictionary, "银行"); // "yínháng"
convert(dictionary, "行长"); // "hángzhǎng"
convert(dictionary, "我要去北京。"); // "Wǒ yào qù Běijīng."

In a browser, serve the package’s data/ directory and fetch it instead:

import { convert, fetchSource, loadDictionary } from "@kensio/pinyinjs";
const dictionary = await loadDictionary(fetchSource("/data"), "standard");
convert(dictionary, "长城"); // "Chángchéng"

Installing the package installs a pinyinjs command, which is the quickest way to try any of this.

Terminal window
$ pinyinjs convert 我要去北京。
Wǒ yào qù Běijīng.
$ pinyinjs explain 银行
银行 yínháng
yín locked
háng word xíng +24.6 héng +26.6 hàng +27.6
$ pinyinjs syllable nǐhǎo
nǐhǎo nǐ hǎo
nǐ n + i, tone 3 nǐ ni3 ni³
hǎo h + ao, tone 3 hǎo hao3 hao³
  • Decodes with a lattice, not longest match, so 银行 is yínháng and 行长 is hángzhǎng.
  • Writes 正词法 word spacing. Aspect particles attach to their verb, suffixes to their stem, and the generic half of a place name separates and capitalises.
  • Applies tone sandhi to 一 and 不 across word boundaries, with third-tone sandhi available and off by default.
  • Says how sure it was. Every syllable comes back locked, backed by a word, or uncertain, with the readings it was chosen over and what they would have cost.
  • Handles both scripts. 简体 and 繁體 are keys in the same dictionary, and the reading locale is a separate option from the script.
  • Ships three dictionary tiers, from 70 KB of single characters to 2.4 MB of every word, nested so a page can convert with one while the next arrives.
  • Works without a dictionary too. Parsing, writing, splitting and sandhi for written pinyin need no data and no network.

Apache-2.0 for the code. Because CC-CEDICT is CC BY-SA 4.0, the compiled dictionaries in data/ are share-alike.