Levenshtein Edit Distance Calculator for Two Strings
The Levenshtein edit distance calculator measures how different two strings are by finding the smallest number of single-character insertions, deletions, and substitutions that changes the first string into the second.
Run — free
Paste or submit a source string and a target string to receive the distance together with both character counts. The calculation is deterministic, case-sensitive, whitespace-sensitive, and Unicode-aware, making it useful for validating algorithms, comparing user input, and building reproducible text-matching workflows.
What Levenshtein distance measures
Levenshtein distance turns a comparison between two strings into one clear integer. A distance of zero means the strings are identical. A distance of one means one insertion, deletion, or substitution is sufficient, while larger values describe the shortest possible sequence of those operations. For example, changing <code>kitten</code> into <code>sitting</code> requires three edits: two substitutions and one insertion. The metric considers position and order, so it provides more information than simply counting characters that differ. It is also symmetric: comparing the source with the target produces the same distance as comparing the target with the source. The result is an absolute edit count, not a percentage or similarity score. That distinction matters when comparing strings of very different lengths, because a distance of three can be substantial for a four-character code but minor for a long paragraph. This calculator returns the source and target character counts beside the distance so you have the context needed to interpret the number correctly.
How the calculation handles text
The calculator compares the strings exactly as supplied. Uppercase and lowercase letters are different, leading and trailing spaces count, punctuation is significant, and no Unicode normalization is performed. This behavior makes the output predictable and prevents hidden cleanup from changing the question you asked. Characters are read as Unicode code points rather than UTF-16 code units, so a common emoji is counted as one character instead of two surrogate halves. Some visually combined symbols, such as a letter followed by a combining accent or a multi-code-point emoji sequence, can still contain more than one code point. If your application needs visually equivalent text to match, normalize both strings according to your own policy before submitting them. Internally, the algorithm uses dynamic programming to evaluate the minimum cost of reaching every relevant prefix. It retains only two rows of that calculation, reducing memory use to the length of the shorter string while preserving the standard Levenshtein result. Each string is limited to 5,000 Unicode code points to keep the quadratic computation bounded.
Using the result in real systems
Edit distance is useful anywhere near-matches need to be ranked or inspected. Search systems can use it as one signal when suggesting corrections, data pipelines can flag names or identifiers that may contain typographical errors, and test suites can assert that a text transformation stays within an expected edit budget. Avoid treating one raw threshold as universally meaningful. A distance of two may identify a plausible typo in a long product name but may represent an entirely different short account code. A common approach is to consider the returned distance together with the longer string length, the language, and the consequences of a false match. Levenshtein distance also assigns the same cost to every insertion, deletion, and substitution; it does not know that adjacent keyboard letters are easier to mistype or that swapping two neighboring characters is common. For those cases, use this value as a transparent baseline and combine it with domain-specific rules rather than presenting it as proof that two records refer to the same thing.
What you can do with it
Check spelling suggestions
Rank candidate corrections by the minimum edits required to turn a typed query into each known term.
Detect near-duplicate records
Compare names, labels, or reference strings and send close matches to a review step instead of merging them automatically.
Test text transformations
Assert an exact edit distance between an original value and transformed output in deterministic automated tests.
FAQ
What operations count as one edit?
Inserting one character, deleting one character, or substituting one character for another each costs one edit.
Is the comparison case-sensitive?
Yes. Uppercase and lowercase characters are different unless you convert both inputs to the same case before submitting them.
Does whitespace affect the distance?
Yes. Spaces, tabs, and line breaks are preserved and compared exactly as supplied.
How are emoji and Unicode text counted?
The calculator works with Unicode code points, so common emoji are not split into UTF-16 surrogate halves. Combined visual symbols can still contain multiple code points.
Does it calculate Damerau-Levenshtein distance?
No. Swapping two adjacent characters is not a single operation here; it is handled through the standard insertion, deletion, and substitution rules.
What does an API request cost?
Each API request costs $0.002. The browser version runs locally without a paid request.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/dev/levenshtein \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"source":"kitten","target":"sitting"}'const res = await fetch("https://api.kit.forhosting.com/dev/levenshtein", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"source": "kitten",
"target": "sitting"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/dev/levenshtein",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"source": "kitten",
"target": "sitting"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/dev/levenshtein", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"source":"kitten","target":"sitting"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"source":"kitten","target":"sitting"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/dev/levenshtein", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"source": "kitten",
"target": "sitting"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "dev.levenshtein",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_chars | 5000 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |