Unicode NFKC normalizer
file ㎞ ① becomes file km 1: ligatures, fullwidth letters, circled digits and other styled variants fold into plain text, and accents are then recomposed, so copies of one name finally match in search and duplicate checks. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Text
- file ㎞ ①
- Result
- file km 1
- Form
- NFKC
- Input length
- 7
- Output length
- 9
This Unicode NFKC normalizer takes any Unicode string and returns its Normalization Form KC result: compatibility decomposition followed by canonical composition as defined in Unicode Standard Annex 15. That path folds presentation forms that look different in storage but should match for search, indexing, and identity checks—fi ligatures become plain f and i, fullwidth Latin letters become ASCII A–Z, circled digits become ordinary numbers, blackletter and mathematical styled letters collapse toward base letters, and sequences such as e plus combining acute compose to a single precomposed character when one exists. Developers use NFKC when building deduplication keys, URL slug pipelines, and catalog search so that visually equivalent compatibility variants do not appear as separate records. Use the free browser path to inspect folds before you wire the identical algorithm into automation.
What NFKC does and how it differs from NFC
Unicode defines four normalization forms. NFC and NFD operate only on canonical equivalence: they recompose or decompose characters that the standard treats as the same abstract character, such as precomposed é versus e plus combining acute. NFKC and NFKD go further by applying compatibility mappings first.
Compatibility mappings intentionally discard presentation distinctions that matter for typography but not for matching: the single-code-point fi ligature becomes the two characters f and i; fullwidth digits and Latin letters map to their halfwidth ASCII counterparts; superscript and subscript digits fold to ordinary digits; fraction characters expand into digit sequences with a fraction slash; and many enclosed or styled letterforms reduce toward a simpler base. After that compatibility decomposition, NFKC runs the same composition step as NFC so the final string is both compatibility-folded and canonically composed.
Choose NFC when you must preserve ligatures and fullwidth styling as distinct glyphs for display fidelity. Choose NFKC when equality, search, and hashing should treat those variants as the same text. This capability always applies NFKC and labels the form in the response so clients never guess which algorithm ran.
Where an NFKC normalizer earns its keep in real pipelines
Search and catalog systems normalize product titles and user-entered names with NFKC before indexing so that a fullwidth brand string and its ASCII twin land on the same token. Content pipelines that generate URL slugs apply NFKC first so ligatures and compatibility symbols do not produce opaque percent-encoded surprises later. Data quality jobs compare records after NFKC to catch near-duplicates that differ only by styled Unicode variants copied from PDFs or office documents.
Security and identity checks sometimes normalize usernames or labels with NFKC before equality tests, reducing look-alike compatibility forms that are not true homoglyph attacks but still break exact-match gates. Localization engineers use the free browser tool on this page to confirm how a sample phrase folds before they bake the same form into acceptance tests.
What you can do with it
Search and catalog deduplication
Normalize titles and names with NFKC before indexing so ligatures, fullwidth letters, and compatibility digits match the same search keys.
Slug and URL pipelines
Fold compatibility characters before slug generation so styled Unicode from copy-paste does not produce unexpected path segments.
FAQ
What is Unicode NFKC normalization?
NFKC is Normalization Form Compatibility Composition from UAX #15: compatibility decomposition of presentation forms, then canonical composition. It folds ligatures and styled characters into a stable composed string for matching and search.
How is NFKC different from NFC?
NFC only handles canonical equivalence (for example composing e plus acute into é). NFKC also applies compatibility mappings such as fi→fi and fullwidth A→A before composing, which is better for equality and indexing.
How is NFKC different from NFKD?
Both apply the same compatibility folding first. NFKD stops there and leaves accents as separate marks, while NFKC then recomposes them, so an e followed by a combining acute ends up as the single letter é.
When should I avoid NFKC?
When ligatures, fullwidth forms or styled letters must stay visible as they are, for example in a typeset display copy. NFKC discards those presentation differences on purpose, so use NFC for display and NFKC for matching, search and duplicate checks.
What happens to fullwidth letters and superscript digits?
They fold to their ordinary forms: fullwidth Latin letters become plain A to Z, superscript and subscript digits become normal digits and fraction characters expand into digits with a fraction slash. Text pasted from PDFs or office files then matches what people type.
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-nfkc \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"file ㎞ ①"}'const res = await fetch("https://api.kit.forhosting.com/enc/unicode-nfkc", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "file ㎞ ①"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/enc/unicode-nfkc",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "file ㎞ ①"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/enc/unicode-nfkc", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"file ㎞ ①"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"file ㎞ ①"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/enc/unicode-nfkc", 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 ㎞ ①"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "enc.unicode_nfkc",
"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
The endpoint is pure parse work: the same input always yields the same output, with no network calls, no model tokens, and no date-dependent behaviour. Failed validation returns invalid_input and is not billed; successful calls cost the published $0.002 base price.
What NFKC does and how it differs from NFC
The result field is the normalized string; text echoes the input; input_length and output_length report JavaScript string lengths before and after normalization; changed is true when the output differs from the input byte-for-character identity; and standard names UAX 15 so documentation and audits stay aligned with the Unicode specification rather than an ad-hoc fold table.
Input contract, response shape, and error behaviour
Missing text fails with a clear missing-field message. Empty strings are valid and normalize to empty with changed false. Because the implementation uses the host ECMAScript normalize path for form NFKC, goldens and production share the same deterministic mapping for every scalar the engine supports. POST a JSON object with a required text field containing the Unicode string to normalize. Aliases input, value, s, and data are accepted so forms, query helpers, and SDK clients can reuse familiar names without renaming columns. The value must be a string; finite numbers and booleans are coerced to their decimal or true/false text forms for convenience in scripting shells, while objects, arrays, null alone as the body shape without a field, NaN, and Infinity fail with invalid_input and a message that names the problem. Strings longer than sixty-five thousand five hundred thirty-six characters are rejected to keep Worker memory predictable. On success the body always includes result, the echoed text, form fixed to the string NFKC, input_length, output_length, a boolean changed, and a standard label pointing at Unicode NFKC compatibility composition. Pair this endpoint with a code-point converter when you need to inspect U-plus tokens before and after the fold, or with case-folding tools when search requires both NFKC and case insensitivity. Invalid requests are not charged; only successful normalizations consume the item price of $0.002.
Where an NFKC normalizer earns its keep in real pipelines
Keep payloads under the length limit, treat invalid_input as a client bug to fix rather than a retryable server error, and document that you chose NFKC deliberately when display-preserving NFC would have been the wrong default for matching.
Integration use cases
Golden tests for text identity
Pin NFKC outputs for ligatures, combining marks, and compatibility squares in CI so libraries cannot silently change fold behaviour.
Technical questions
What input does the Unicode NFKC normalizer accept?
Send a JSON object with required string field text (aliases input, value, s, data). Missing text, non-string objects/arrays, non-finite numbers, and strings over 65536 characters return invalid_input.
What does the response include?
result is the NFKC string; text echoes the input; form is always NFKC; input_length and output_length are character lengths; changed is true when normalization altered the string; standard names UAX #15.
What does the Unicode NFKC normalizer cost?
The browser tool is free. API requests use prepaid KIT balance at $0.002 per successful call; invalid input is not billed.