kebab-case converter
kebab-case lowercases everything and joins words with hyphens: parse-xml-file, main-content, data-user-id. It is the web platform’s native style — CSS properties and class names, HTML attributes, custom element names, npm packages and URL paths are all kebab-case, and several of those are mandated rather than conventional.
The hyphen is also exactly why it cannot be an identifier in most programming languages: the parser reads it as subtraction, so parse-xml-file is an expression, not a name. Lisp dialects and Clojure are the exceptions, where hyphens are ordinary symbol characters. That split is worth remembering when converting a set of names — kebab-case output is for markup, URLs and configuration, never for a variable.
Two rules the web actually enforces. A custom element name must contain a hyphen — <user-card> is valid and <usercard> is not, which is how the browser tells your elements from future standard ones. And HTML data-* attributes map to the dataset API by converting kebab-case to camelCase: data-user-id becomes dataset.userId, an automatic conversion that surprises people who expected the literal name.
kebab-case — worked through
Every line below is produced by the same converter that runs on this page, so the example and the tool cannot disagree.
| Input | kebab-case | Note |
|---|---|---|
| parse xml file | parse-xml-file | The canonical shape of this style. |
| Parse the XML file from the ERP API | parse-the-xml-file-from-the-erp-api | Acronym preservation on — the converter’s default. |
| Parse the XML file from the ERP API | parseTheXMLFileFromTheErpAPI | Converted back to camelCase. Listed acronyms are restored; anything not on the list returns as an ordinary word. |
Where kebab-case is the convention
| Ecosystem | What it applies to |
|---|---|
CSS | Properties (background-color) and the class-naming conventions built on it — BEM’s block__element--modifier is kebab-case with structure added. |
HTML | Attributes, and custom element names where a hyphen is REQUIRED by the standard so author elements never collide with future built-ins. |
URLs | Path segments and slugs. Search engines have long treated hyphens as word separators and underscores as joiners, which settled the argument in practice. |
npm & CLI | Package names and command-line flags (--dry-run). npm forbids uppercase in new package names outright, so kebab-case is the only option left. |
The acronym trap
Everything lowercases, so XML becomes xml and the output is unambiguous: parse-xml-file. The trap is the return trip, and the web has a specific version of it — the HTML dataset API converts data-user-id to dataset.userId automatically, so a data attribute containing an acronym (data-xml-url) arrives in JavaScript as dataset.xmlUrl, never dataset.XMLUrl. Name attributes with that conversion in mind and the JavaScript side stays predictable.
مرحبا بالعالم. The Unicode slug keeps the original script.FAQ
What is the difference between kebab-case and a slug?
A slug is kebab-case plus URL-safety work: transliterating accents and non-Latin scripts, dropping punctuation, optionally removing stop words and trimming to a length. Every slug is kebab-case; not every kebab-case string is a safe slug.
Why can I not use kebab-case for variable names?
Because the hyphen is the subtraction operator in nearly every language, so the parser reads it as an expression. Lisp and Clojure are the exceptions — there hyphens are ordinary symbol characters and kebab-case is idiomatic.
Why must a custom element name contain a hyphen?
The HTML standard reserves single-word tag names for itself, so an author-defined element must have at least one hyphen — <user-card> is valid, <usercard> is not. It guarantees your elements can never collide with a future built-in.