Unicode NFKD normalizer
file ① café becomes file 1 café with the accent split off: ligatures expand into separate letters, circled digits become plain numbers and accented letters break into base plus mark, with nothing recomposed afterwards. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Text
- file ① café
- Result
- file 1 café
- Form
- NFKD
- Input length
- 10
- Result length
- 12
Unicode text often carries the same abstract characters in multiple coded forms: a single ligature glyph, a precomposed letter with accent, a circled digit, or a sequence of base characters plus combining marks. Search engines, databases, and security filters need a single stable form so that file and file match, café and café compare equal after decomposition, and ① does not hide a digit. Unicode Normalization Form KD (NFKD) applies compatibility decomposition: it expands ligatures, strips presentation-only differences, and separates combining sequences without recomposing them.
What NFKD does and how it differs from NFC, NFD, and NFKC
Unicode Normalization Form KD, defined in Unicode Standard Annex fifteen, is the compatibility decomposition form. Unlike NFD, which only applies canonical decompositions such as splitting a precomposed é into e plus combining acute, NFKD also applies compatibility mappings that remove formatting and presentation distinctions that are not semantically essential for many matching tasks. Ligatures such as the single character fi become the two letters f and i; the double-f ligature ff becomes f f; the triple ligature ffi becomes f f i.
Circled numbers, fullwidth digits, superscripts, and similar compatibility characters expand into their plain counterparts. Canonical combining sequences still appear in decomposed order, so café may become cafe followed by a combining acute accent on the e. NFKD deliberately does not recompose: that recomposition step belongs to NFKC.
Choosing NFKD is appropriate when you want maximum unfolding for indexing, fuzzy compare, or stripping presentation forms before further processing. Choosing NFC is better when you want a compact composed form for storage and display. The implementation uses the host language built-in String normalize method, which follows UAX fifteen and is fully deterministic across modern JavaScript engines.
Where Unicode NFKD normalization shows up in real work
Search and catalog systems normalize product titles and user-facing labels so that ligature-rich typography from design tools does not create duplicate keys: final and final collapse after NFKD. Localization engineers compare user strings after compatibility decomposition when hunting confusable lookalikes or verifying that a display form is only presentation sugar over plain letters. Security and identity pipelines often apply NFKD or NFKC before hashing or equality checks so that alternative Unicode spellings of the same abstract name cannot bypass allow lists.
Programming courses teach encoding by showing that one visible character can map to several scalars after decomposition; a dedicated NFKD landing serves that search intent better than burying it under Base64 or code-point converters. Support desks paste odd symbols from tickets and need an authoritative unfolded form for engineering reproduction. If you need code-point U-plus lists, HTML entity encoding, or UTF-8 mojibake repair, treat those as separate search intents and landings rather than overloading this Unicode NFKD normalizer page.
What you can do with it
Search and catalog key folding
Normalize product titles and labels with NFKD so ligatures and circled digits do not create duplicate index keys next to their plain-text equivalents.
Identity and security compare
Compatibility-decompose usernames and tokens before equality or hashing so presentation variants cannot bypass filters that expect plain ASCII-friendly forms.
FAQ
What is Unicode NFKD?
NFKD is Normalization Form KD from Unicode Standard Annex #15: full compatibility decomposition. It unfolds ligatures and compatibility characters and separates combining marks, without recomposing them.
How is NFKD different from NFKC?
Both apply compatibility decomposition. NFKC then recomposes where possible into composed characters. This tool returns NFKD only (decomposed form, no recomposition).
Will file become file?
Yes. The fi ligature U+FB01 is a compatibility character; NFKD maps it to f + i, so file normalizes to file with changed true.
What happens on invalid input?
Missing text, non-string objects, non-finite numbers, and oversized strings are rejected with a clear message. Validation failures are not charged.
What does it cost?
The browser tool is free and runs locally.
Related tools
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/enc/unicode-nfkd \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"file ① café"}'const res = await fetch("https://api.kit.forhosting.com/enc/unicode-nfkd", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "file ① café"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/enc/unicode-nfkd",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "file ① café"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/enc/unicode-nfkd", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"file ① café"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"file ① café"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/enc/unicode-nfkd", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"text": "file ① café"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "enc.unicode_nfkd",
"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.
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. |
Technical notes
This capability accepts any string, runs the standard NFKD algorithm, and returns the normalized result with length and code-point statistics plus a boolean that tells you whether anything changed. Invalid or missing input fails with invalid_input so bad payloads never invent text. The free browser tool and the paid API share the same pure module, so classroom demos, localization pipelines, and production webhooks always agree.
What NFKD does and how it differs from NFC, NFD, and NFKC
This endpoint always returns form NFKD so clients never have to guess which algorithm ran.
Input contract, response fields, and error behaviour
Empty strings are valid and return an empty NFKD result with changed false. Strings longer than sixty-five thousand five hundred thirty-six UTF-16 code units fail so runaway pastes cannot exhaust the worker. Missing text fails immediately without billing. Send a JSON object with a required string field named text. Aliases input, value, s, and data are accepted when text itself is absent, matching sibling encoding tools. Numbers and booleans are coerced to their decimal or true or false string forms; objects, arrays, null, NaN, and Infinity are rejected with invalid_input naming the problem. On success the body echoes the original text, provides result as the NFKD-normalized string, sets form to the constant NFKD, sets changed to true when result differs from text, reports input_length and result_length as UTF-16 unit counts, reports input_code_points and result_code_points as Unicode scalar counts so emoji and non-BMP characters are not miscounted, and includes a short standard label pointing at UAX fifteen. Example: the ligature word file becomes file with changed true and a larger result_length because one code unit became four. Pricing for successful API calls is the published base of $0.002 per item; validation failures do not consume prepaid balance.
Where Unicode NFKD normalization shows up in real work
Because this capability is a pure parse engine, API pricing is the published base of $0.002 per successful item and failed validation does not consume balance.
Integration use cases
Localization and teaching fixtures
Generate stable decomposed strings for golden tests, glyph coverage checks, and classroom demos of UAX #15 compatibility mappings.