Convert camelCase to kebab-case

Convert camelCase JavaScript property names to kebab-case for CSS, HTML attributes, and URL slugs. Splits on camelCase boundaries and joins with hyphens.

ZERO UPLOAD · ALL LOCAL
  1. Type or paste text into the input box — all 14 conversions appear instantly.
  2. The Character Case Formats section shows 5 character-level transformations.
  3. The Word Case Formats section shows 9 word-level transformations.
  4. Use the Copy buttons to grab any individual result.
  5. Click "Use as input" to chain conversions (e.g. snake_case → camelCase → kebab-case).

Worked examples for this use case

JavaScript design tokens → CSS custom property names

Before
colorPrimary
spacingMd
fontSizeBody
borderRadius
After
color-primary
spacing-md
font-size-body
border-radius

React prop names → HTML data attributes

Before
userId
productName
categoryId
After
user-id
product-name
category-id

INPUT TEXT

CHARACTER CASE FORMATS

lower case
UPPER CASE
Capitalized Case
aLtErNaTiNg cAsE
InVeRsE CaSe

WORD CASE FORMATS

camelCase
PascalCase
snake_case
SCREAMING_SNAKE
kebab-case
dot.case
path/case
sentence case
Title Case

camelCase to kebab-case Converter

Design systems often expose token names as camelCase JavaScript keys, but CSS and HTML need kebab-case equivalents. When you map those names to CSS custom properties or HTML data attributes, you need to convert the format.

Yet hyphens are subtraction operators in JavaScript, TypeScript, Python, and Java. Consequently, kebab-case is not valid in those languages as an identifier: it only appears in CSS, HTML attributes, URL slugs, and CLI flags.1

Where camelCase identifiers need kebab-case equivalents

CSS custom properties use a two-hyphen prefix followed by kebab-case names, such as a property named background-color after the prefix. When a design system exports tokens as JavaScript object properties (backgroundColor, fontSizeLarge), the CSS variable equivalents require kebab-case names. HTML data attributes also require kebab-case: data-user-id, data-product-name.2 The same rule applies to SVG attributes presented as kebab-case in markup, since presentation attributes like stroke-width and fill-opacity follow the same hyphenated convention across the entire document object model.

CSS custom properties and data attributes

CSS custom properties use a two-hyphen prefix followed by kebab-case names, such as a property named background-color after the prefix. When a design system exports tokens as JavaScript object properties like "backgroundColor" or "fontSizeLarge", the CSS variable equivalents require kebab-case names. HTML data attributes follow the same convention: "data-user-id" and "data-product-name" are kebab-case, even though the corresponding JavaScript dataset properties use camelCase. Building on this, CLI tools and npm scripts commonly use kebab-case flags, which correspond to camelCase options in the underlying configuration objects.

The reverse mapping also happens constantly in JavaScript. When you read a data-user-id attribute through the DOM dataset API, the browser hands your code the camelCase key userId, so the kebab-case source and the camelCase key are two views of one attribute. Keeping both names derived from the same token prevents the mismatch where a CSS file declares --user-id but the script reads dataset.userId with a different casing. Design systems that document their tokens once and generate both the CSS variables and the dataset keys from that source avoid maintaining two name lists that can drift apart.

Edge cases: acronyms, numbers, and consecutive capitals

Acronyms split at each capital letter boundary: "parseHTML" becomes "parse-h-t-m-l". Numbers act as word boundaries: "h1Tag" becomes "h1-tag". Consecutive capitals that form an acronym,like the "HTTP" in "parseHTTPResponse",split letter by letter. For cleaner output with acronyms, use title-cased acronyms in the source: "parseHttpResponse" converts cleanly to "parse-http-response". HTML element references like "h1Heading" produce "h1-heading", keeping the number with its original segment. CamelCase strings that contain multiple words without clear boundaries, such as "XMLHttpRequest", can produce surprising kebab-case output; normalizing to "XmlHttpRequest" before conversion yields the more readable "xml-http-request". Empty lines and whitespace-only lines pass through unchanged, so formatting a multi-line paste with blank separators between logical groups does not produce unwanted hyphens.

Workflow: converting design token names to CSS variables

Building on this, a practical workflow: your design system defines tokens as JavaScript constants,colorPrimary, spacingMd, fontSizeBody. To write a CSS file with custom properties, paste all the constant names into this converter and copy the kebab-case output. Each name becomes a CSS custom property name: color-primary, spacing-md, font-size-body. Add the two-hyphen prefix and you have your :root declarations. CapyToolkit converts each line independently. When tokens come from a tool like Figma or Tokens Studio, the export format may use camelCase or dot-separated paths. Converting the exported names to kebab-case before writing them into your stylesheet ensures they match CSS custom property naming rules. For design systems that support multiple themes, prefixing the kebab-case output with a theme segment (dark-color-primary, light-color-primary) creates self-documenting variable names that developers can search for across the entire codebase.

Vue.js component props: camelCase in JavaScript and kebab-case in templates

Vue.js distinguishes between camelCase and kebab-case at the component boundary. JavaScript component options use camelCase for prop names; Vue template syntax requires kebab-case for the same props. Converting between these two formats is the most common Vue naming task when building reusable components, and this converter handles the split cleanly for any prop list you paste into the input field.

A Vue component defined with props: { userId: String, firstName: String } uses camelCase internally. In a parent template, you reference those props with kebab-case attributes: <UserCard :user-id="id" :first-name="name" />. Vue's template compiler handles this conversion automatically for HTML attribute syntax, but understanding the mapping prevents confusion when reading templates that use kebab-case prop names for props defined as camelCase in the component options.3

Converting prop names for v-bind and dynamic bindings

Dynamic bindings in Vue with v-bind or : shorthand follow the same kebab-case requirement in HTML templates. If you have a camelCase list of prop names from a component interface and want to write the template binding attribute names, paste them into this converter and use the kebab-case output in the template. "borderRadius" becomes "border-radius" as an attribute in the template. For Composition API components using defineProps, the camelCase names are used in the <script setup> block and the kebab-case equivalents in the template.

Generating Tailwind CSS utility class names from design token identifiers

Tailwind CSS generates utility class names from its configuration object, which uses camelCase keys. When you extend Tailwind's theme or add custom utilities, the configuration uses camelCase, but the resulting class names in HTML templates use kebab-case. Converting your camelCase token names to kebab-case before checking the generated class name helps verify your configuration is correct.

A Tailwind theme extension like theme: { extend: { fontSize: { bodyLarge: '18px' } } } generates the class text-body-large. The camelCase key bodyLarge becomes the kebab-case class suffix body-large.4 Paste your camelCase token key names in to check the class suffix Tailwind builds before adding them to the configuration. This prevents surprises where the class name you expect does not match what Tailwind generates.

JIT mode and dynamic class name generation

Tailwind's JIT (just-in-time) mode scans your template files for class names and generates only the CSS that is actually used. Dynamic class name construction like `text-${size}` does not work because JIT cannot detect string-concatenated class names at build time. You must write the full class name as a static string. Converting your token identifiers to kebab-case and writing the full class names statically in your template files ensures JIT generates the correct CSS.4 CapyToolkit converts each line independently, so checking a full design token list takes one paste.

When to use this

Use this when converting JavaScript design token names to CSS custom properties, mapping camelCase prop names to HTML data attributes, or generating kebab-case URL slugs from JavaScript identifiers.

Examples

JavaScript design tokens → CSS custom property names

Before
colorPrimary
spacingMd
fontSizeBody
borderRadius
After
color-primary
spacing-md
font-size-body
border-radius

React prop names → HTML data attributes

Before
userId
productName
categoryId
After
user-id
product-name
category-id
Sources
  1. 1.

    Mozilla Developer Network, "Kebab case - Glossary," developer.mozilla.org, July 2025. https://developer.mozilla.org/en-US/docs/Glossary/Kebab_case

  2. 2.

    W3C, "CSS Custom Properties for Cascading Variables Module Level 1," w3.org, June 2022. https://www.w3.org/TR/css-variables-1/

  3. 3.

    Vue.js, "Components Basics," vuejs.org, accessed June 2026. https://vuejs.org/guide/essentials/component-basics

  4. 4.

    Tailwind Labs, "Detecting classes in source files - Core Concepts," tailwindcss.com, accessed June 2026. https://tailwindcss.com/docs/detecting-classes-in-source-files

FAQ