transliteration

Converts Unicode text from any writing system into Latin ASCII or URL-safe slugs, with zero runtime dependencies.

Library
npm
v2.6.1
640stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
40/100Fair
Development Activity4
Maintenance20
Community56
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
75/100Good
Architecture78
Code Quality86
Innovation82
Learning Curve55

transliteration is a JavaScript/TypeScript library exposing two functions, transliterate() and slugify(), that convert Unicode strings (Chinese, Korean, Greek, Cyrillic, and other scripts) into their closest Latin/ASCII equivalents using a large embedded character map. It ships a full build covering the whole map (~186 KB) alongside a separate, much smaller transliteration/latin entry point (~5 KB) restricted to Basic Latin and Latin Extended ranges, so consumers who only need Western-European coverage can opt out of the larger CJK/Korean data. The package runs identically across Node.js, browsers, Web Workers, React Native, and Electron, ships bundled TypeScript type definitions, and has no runtime dependencies at all.

Beyond the core API, transliterate() and slugify() both expose config() and setData() methods for setting persistent global defaults or overriding parts of the character map, plus per-call options for custom replace/ignore string handling, Chinese-specific spacing fixes, and slug casing/separator control. Two CLI binaries, transliterate and slugify, wrap the same logic for shell scripting and stdin piping use cases.

What You Get

  • transliterate() and slugify() functions - core API for Unicode-to-Latin conversion and URL-safe slug generation
  • Latin-only build variant - the transliteration/latin sub-path ships a ~5 KB bundle instead of ~186 KB by dropping CJK/Korean/etc. charmap data
  • Bundled TypeScript types - full .d.ts definitions ship in dist, no separate @types/transliteration package needed
  • CLI binaries - transliterate and slugify commands for shell scripting and stdin piping
  • Cross-platform builds - separate CJS (Node), ESM, and UMD bundles cover browser, Web Worker, React Native, and Electron usage

Common Use Cases

  • Generating SEO-friendly URL slugs - convert post titles or user-generated names in any language into ASCII slugs for routes
  • Normalizing multilingual user input - transliterate names or addresses from CJK, Cyrillic, Greek, or Korean into a Latin-searchable form
  • Filename sanitization - strip Unicode from user-uploaded filenames while keeping them readable
  • Command-line text conversion - call the CLI from build scripts or shell pipelines to romanize text files

Under The Hood

Architecture The library is organized as a layered common/platform split: src/common holds platform-agnostic core classes (Transliterate in transliterate.ts, Slugify extends Transliterate in slugify.ts, plus shared regex/range helpers in utils.ts), while src/node, src/browser, and src/cli each compose those primitives into a distinct entry point - src/node/index.ts and src/browser/index.ts bind Transliterate/Slugify instances into plain function exports with attached .config/.setData methods, and src/cli wraps the same classes with a hand-rolled, zero-dependency argument parser in cli/common.ts. transliterate() runs a four-stage pipeline (pre-replace, charmap walk with surrogate-pair-aware iteration in codeMapReplace, optional trim, post-replace), and slugify() calls transliterate() then pipes the result through an allowedChars strip and separator collapse. The charmap itself (generated by scripts/generate-data.ts) is treated as immutable unless explicitly overridden via setData(), so the Transliterate class constructor is the single real coupling point shared by every downstream entry point.

Tech Stack Written in TypeScript targeting ES2020, built with tsup (esbuild-based) into four separate output profiles - node CJS with .d.ts, browser ESM, browser UMD (global name transliteration), and CLI binaries with a shebang banner - and published with zero runtime dependencies. The dev toolchain uses Bun as both package manager and script runner, Vitest with v8 coverage and happy-dom for browser-environment tests, and Biome (via the ultracite preset) for combined linting and formatting in place of a traditional ESLint+Prettier pair. CI runs lint, build, and coverage-tracked tests on every push/PR via GitHub Actions, uploading results to Codecov, with a second workflow auto-publishing to npm once a build succeeds against an untagged version.

Code Quality Every core module has a co-located test file (transliterate, slugify, utils, latin, cli, and browser index all have matching *.test.ts files), run through Vitest with coverage enforced in CI. The sampled source shows explicit typed function signatures throughout, narrow exported types, and deliberate defensive choices - an iterative binary search replacing recursion in inRange for performance, and a documented ReDoS-safe fallback regex in the custom replace path. Complexity-suppression comments are annotated with a stated reason rather than silently disabled, and coverage-ignore markers call out intentionally untested defensive branches. No error-swallowing patterns were observed in the sampled files, and the strict Biome preset gates merges in CI.

API Design The public surface is deliberately small: two exported functions, transliterate() and slugify(), each taking a string plus an optional options object, with .config()/.setData() attached for global customization so consumers never need to instantiate the underlying classes directly. Zero configuration is required to get useful output, while a documented options table (ignore, replace, replaceAfter, trim, unknown, separator, allowedChars, fixChineseSpacing) covers the edge cases the README’s own Known Issues table calls out. Option naming is consistent between transliterate and slugify, the CLI mirrors the same flag semantics as the JS options, and bundled TypeScript types give consumers autocomplete without an extra @types install.

Used by 5 apps in this directory

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search