Converting Between Camel, Snake, and Kebab Case in JavaScript

In Brief
Case conversion works by tokenising the supported input before joining the tokens in the target format. This article's utility recognises spaces, hyphens, underscores, lower‑to‑upper transitions, and acronym‑to‑word transitions, keeps digits in the tokens, and collapses repeated separators. The final step joins those tokens as camel case, Pascal case, snake case, or kebab case.
When working in web development, text formatting can play a crucial (and sometimes underappreciated) role, particularly when handling variable or file names, API responses, and configuration settings. Different naming conventions (i.e., camel case, snake case, and kebab case) are widely used in JavaScript and software development in general, depending on the context.
Today, I intend to explore how we can go about converting between these different word cases using JavaScript, and discuss some of the most common use cases and best practices. By the end, you should have a decent understanding of how to manipulate text formatting in JavaScript, depending on your specific needs.
Understanding Naming Conventions
Before diving into the conversions themselves, let's take a moment to clarify the three most common naming styles:
camelCaseis often used in JavaScript variable names, where each word after the first starts with an uppercase letter (e.g.,theVariableName).snake_caseseparates lowercase words with underscores, commonly used in database fields and Python variables (e.g.,the_variable_name).kebab-caseseparates lowercase words with hyphens instead of underscores and is frequently used in URLs and CSS class names (e.g.,random-variable-name).
Converting a String of Text into Different Cases
It is very common in front‑end development to find that you need to process text by converting a space‑separated phrase into one of the specific naming conventions I've described above. For example let's look at, converting "random variable name" into camel case, snake case, and kebab case.
Sanitising the String
Before we apply any conversion to a string like this, we need to prepare it by cleaning up the input. We need to:
Trim spaces:
Remove leading and trailing spaces.Handle multiple spaces
: Convert multiple spaces into a single space.Remove special characters
: Strip out any non‑alphanumeric characters, keeping only letters, numbers, and spaces.
So, here's a utility function that does exactly that:
const sanitiseString = (str: string): string =>
str.trim().replace(/[^a-zA-Z0-9\s]/g, "").replace(/\s+/g, " ");Converting a String to camelCase
So, with sanitisation handled, we can convert our strings into camelCase by:
- Converting the cleaned string to lowercase.
- Use a regular expression to find each word after a space and capitalise its first letter.
- Remove spaces from the final output.
This looks something like this:
const toCamelCase = (str: string): string =>
sanitiseString(str).toLowerCase().replace(/ (\w)/g, (_, char) => char.toUpperCase());
console.log(toCamelCase("random variable name!")); // Output: randomVariableNameA sidenote about PascalCase
PascalCase is common for React component names, classes, and TypeScript types. It is closely related to camelCase: each word begins with a capital, including the first. So instead of randomVariableName (as you would get with camelCase), PascalCase produces RandomVariableName.
As far as implementation is concerned, it's almost an exact copy of the above but with a very slightly different regex so that we capture the first letter as well as the first letter of each following word:
const toPascalCase = (str: string): string =>
sanitiseString(str).replace(/(?:^| )(\w)/g, (_, char) => char.toUpperCase());
console.log(toPascalCase("random variable name!")); // Output: RandomVariableNameConverting a String to snake_case
Unlike camelCase and PascalCase, snake_case retains a physical representation of where the spaces in our string were, by replacing them with underscores (_).
To do this, we:
- Convert the cleaned string to lowercase.
- Replace spaces with underscores.
Something like this:
const toSnakeCase = (str: string): string =>
sanitiseString(str).toLowerCase().replace(/\s+/g, "_");
console.log(toSnakeCase("random variable name!")); // Output: random_variable_nameConverting a String to kebab-case
Much like the relationship between camelCase and PascalCase, kebab-case is a very close relative to snake_case, with hyphens(-) instead of underscores.
It will come as no surprise ‑ then ‑ that implementation is very similar too. To achieve kebab-case, we:
- Convert the cleaned string to lowercase.
- Replace spaces with hyphens.
const toKebabCase = (str: string): string =>
sanitiseString(str).toLowerCase().replace(/\s+/g, "-");Putting It All Together: A Single Utility to Convert to Different Cases
In the real world, we wouldn't necessarily want to maintain separate functions for each case; we would create a utility function that handles whichever case you choose to ask of it.
Something like this:
const convertCase = (
str: string,
format: 'camel' | 'pascal' | 'snake' | 'kebab'
): string => {
const sanitiseString = (str: string): string =>
str
.trim()
.replace(/[^a-zA-Z0-9\s]/g, '')
.replace(/\s+/g, ' ');
const formatted = sanitiseString(str);
switch (format) {
case 'camel':
return formatted
.toLowerCase()
.replace(/ (\w)/g, (_, char) => char.toUpperCase());
case 'pascal':
return formatted.replace(/(?:^| )(\w)/g, (_, char) => char.toUpperCase());
case 'snake':
return formatted.toLowerCase().replace(/\s+/g, '_');
case 'kebab':
return formatted.toLowerCase().replace(/\s+/g, '-');
default:
throw new Error('Unsupported format type');
}
};In this way, we can bundle all the different cases together into one nice and precise utility function.
Why use a regex pattern in replace()?
These examples already use replace(). The choice is whether its first argument is a literal string or a regular expression. A string pattern replaces the first matching occurrence; a regex with the g flag replaces every match. Regex also lets us capture a character and change it in the replacement callback.
- Multiple matches: A regex with the
gflag can replace all matching spaces or separators. For repeated literal strings,replaceAll()is another option. - Captured characters: The pattern can capture the character after a space so the replacement callback can capitalise it.
- Pattern matching: A regex can describe a group of possible characters, such as whitespace, instead of requiring a separate replacement for each one.
- Related conversions: The
camelCaseandPascalCaseexamples use similar patterns, with the latter also matching the first character.
For example, in the toCamelCase() function:
sanitiseString(str).toLowerCase().replace(/ (\w)/g, (_, char) => char.toUpperCase());/ (\w)/glooks for a space followed by a word character. In the sanitised ASCII input here, that character is a letter or digit.- The function capitalises the letter and removes the space.
Converting Between Different Cases
Converting between different cases is more complicated than simply taking a string and converting it to a predefined case pattern. After all, that's what this article is really all about.
So, here's one I prepared earlier:
type CaseFormat = "camel" | "pascal" | "snake" | "kebab";
const tokeniseCase = (value: string): string[] => {
return value
.trim()
.replace(/([a-z0-9])([A-Z])/g, "$1 $2")
.replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2")
.replace(/[^a-zA-Z0-9]+/g, " ")
.trim()
.split(/\s+/)
.filter(Boolean)
.map((word) => word.toLowerCase());
};
const capitalise = (word: string): string => {
return word.charAt(0).toUpperCase() + word.slice(1);
};
const convertBetweenCases = (value: string, targetFormat: CaseFormat): string => {
const words = tokeniseCase(value);
if (words.length === 0) {
return "";
}
switch (targetFormat) {
case "camel":
return words[0] + words.slice(1).map(capitalise).join("");
case "pascal":
return words.map(capitalise).join("");
case "snake":
return words.join("_");
case "kebab":
return words.join("-");
default:
throw new Error("Unsupported format type");
}
};
console.log(convertBetweenCases("random_variable_name", "camel")); // Output: randomVariableName
console.log(convertBetweenCases("randomVariableName", "snake")); // Output: random_variable_name
console.log(convertBetweenCases("random-variable-name", "pascal")); // Output: RandomVariableName
console.log(convertBetweenCases("RandomVariableName", "kebab")); // Output: random-variable-name
console.log(convertBetweenCases("HTTPResponseCode", "camel")); // Output: httpResponseCode
console.log(convertBetweenCases("version__2--API", "kebab")); // Output: version-2-apiHere, we're putting everything together. Before conversion, the utility tokenises ASCII letters and digits using separators, lower‑to‑upper transitions, and acronym‑to‑word transitions as boundaries. It then joins those tokens in the requested format; it does not need to detect and label the original case first.
This works like this:
Tokenises Input
: We usetokeniseCase()to preserve the supported word boundaries before conversion.Handles Acronyms
:tokeniseCase()keeps a run such as HTTP together while creating a boundary before Response in HTTPResponse.Handles Repeated Separators
:tokeniseCase()collapses multiple spaces, underscores, hyphens, or other separators into one boundary; digits remain part of the resulting tokens.Converts to Target Case
: ThetargetFormatvalue determines how the tokens are joined in camel, Pascal, snake, or kebab case.Returns Result
: Empty input returns an empty string; otherwise, the transformed tokens are returned.
Wrapping Up
Formatting and reformatting text in JavaScript is an important skill in web development, especially when working with variable names, API responses, or structured data. Today, we've explored how to convert space‑separated strings into camelCase, PascalCase, snake_case, and kebab-case whilst ensuring that the input is properly sanitised beforehand.
I've also bundled all of this together into a single utility function that preserves word boundaries before transforming the tokens into another naming convention.
Key Takeaways
- Properly sanitising input ensures consistency in case transformations.
- Camel case (
camelCase) and Pascal case (PascalCase) are common in JavaScript, whilst snake case (snake_case) and kebab case (kebab-case) are widely used in APIs and URLs. - A robust conversion utility defines its supported input grammar and preserves word boundaries before joining tokens in the target case.
- Regular expressions provide an efficient way to transform text structures reliably.
Understanding these techniques will help you work more effectively with different naming conventions, making your JavaScript code cleaner and easier to maintain.