Kyori

String distance & similarity for JavaScript

Levenshtein, Damerau-Levenshtein, Hamming, Jaro-Winkler — plus the Kyori ranking algorithm for token-sensitive autocomplete scoring. Pure JavaScript, zero heavy dependencies, MIT-licensed.

In Japanese, 距離 (きょり) means "distance".

npm install @wizhut_tech/kyori
Library · JavaScript & TypeScript · MIT

Five algorithms, one consistent shape.

distance() for edit-distance metrics, similarity() for the score-based ones. Pick the algorithm that fits the problem.

Edit-distance metrics

Lower is more similar — zero means identical.

const { levensthein, damerau_levensthein, hamming } =
  require('@wizhut_tech/kyori')

levensthein.distance('foo', 'food')           // → 1
damerau_levensthein.distance('form', 'from')  // → 1  (transposition)
hamming.distance('karolin', 'kathrin')        // → 3

Similarity scoring

0 means unrelated, 1 means identical — perfect for ranking.

const { jaro_winkler, kyori } =
  require('@wizhut_tech/kyori')

jaro_winkler.similarity('Maria', 'Marie')     // → 0.94
kyori.similarity('foo', 'food')               // → 1
kyori.similarity('rea', 'react native')       // strong prefix match

Use case — autocomplete ranking

Sort a candidate list by how well each item matches the user's query. The Kyori score is the one tuned for this.

const { kyori } = require('@wizhut_tech/kyori')

const query = 'rea'
const candidates = ['react', 'react native', 'redux', 'preact', 'vue']

const ranked = candidates
  .map(name => ({ name, score: kyori.similarity(query, name) }))
  .sort((a, b) => b.score - a.score)

// → [{ name: 'react', ... }, { name: 'react native', ... }, ...]

What's in the box

Five well-known algorithms, picked for the work most JavaScript apps actually need to do.

Levenshtein

Classic edit distance — counts the minimum single-character insertions, deletions, and substitutions to turn one string into another.

Damerau-Levenshtein

Levenshtein plus transpositions, so "form" → "from" costs 1 instead of 2. Better for typo-tolerant matching.

Hamming

Character-by-character difference for equal-length strings. Cheap and useful when alignment is fixed (codes, fingerprints, hashes).

Jaro-Winkler

Tuned for short strings like names — favours matching prefixes, which makes it the right pick for "did you mean…" on people and places.

Kyori ranking

The reason this library exists: a token-sensitive similarity score designed for autocomplete and search ranking, where partial matches and word boundaries should both count.

Zero heavy deps

Pure JavaScript, no native bindings, no transitive bloat. Drops cleanly into Node, the browser, edge runtimes, and bundler-driven SPAs alike.

Ready to drop in

Free, MIT-licensed, no telemetry, no native bindings. Works in Node, the browser, and edge runtimes.