Converting Between Camel, Snake, and Kebab Case in JavaScript

Hero image for Converting Between Camel, Snake, and Kebab Case in JavaScript. Image by Daniela Castro.
Hero image for 'Converting Between Camel, Snake, and Kebab Case in JavaScript.' Image by Daniela Castro.

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 your specific needs.


Understanding Naming Conventions

Before diving into the conversion themselves, let's take a moment to clarify the three most common naming styles:

  • camelCase

    is often used in JavaScript variable names, where each word after the first starts with an uppercase letter (e.g., theVariableName).
  • snake_case

    separates lowercase words with underscores, commonly used in database fields and Python variables (e.g., the_variable_name).
  • kebabcase

    separates lowercase words with hyphens instead of underscores and is frequently used in URLs and CSS class names (e.g., randomvariablename).

Converting a String of Text into Different Cases

It is very common in frontend development to find that you need to process text by converting a spaceseparated 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 nonalphanumeric 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: randomVariableName

A Sidenote About Pascalcase

As an aside, there is another format that I'm choosing not to spend too much time on in this article simply because I find that it isn't often used. The sibling of camelCase, PascalCase, is virtually identical in removing spaces and capitalising each word. The only difference is that it also capitalises the first word. 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 proceeding word:

const toPascalCase = (str: string): string =>  sanitiseString(str).replace(/(?:^| )(\w)/g, (_, char) => char.toUpperCase());console.log(toPascalCase("random variable name!"));  // Output: RandomVariableName

Converting 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_name

Converting a String to Kebab‑Case

Much like the relationship between camelCase and PascalCase, kebabcase 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 kebabcase, 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 Regex instead of replace()?

You may have noticed that once a string is sanitised often all we are doing is replacing one character (i.e., a space) with another character (i.e., a hyphen or an underscore). On the surface, this might seem like a prime opportunity to use replace() instead of more cumbersome and hardtoread regular expressions. However, there is good reason for this, here's why:

  • Handles multiple spaces

    – using Regex allows us to match and replace all matching (i.e., whitespace) occurrences, whereas replace() will generally only match the first instance (unless ironically you pass a Regex into it).
  • Detects word boundaries

    – It ensures proper capitalisation or character replacement for each word in a string.
  • Efficient pattern matching

    Regex provides a structured way to locate and transform text patterns more reliably than multiple replace() calls.
  • Versatility

    – With regex, we can use the same pattern for different cases with only minor tweaks as we've seen above in the camelCase and PascalCase examples.

For example, in the toCamelCase() function:

sanitiseString(str).toLowerCase().replace(/ (\w)/g, (_, char) => char.toUpperCase());
  • / (\w)/g looks for a space followed by a letter.
  • 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:

const convertBetweenCases = (str: string, targetFormat: "camel" | "pascal" | "snake" | "kebab"): string => {  const sanitiseString = (str: string): string =>    str      .trim()      .replace(/[^a-zA-Z0-9\s]/g, "")      .replace(/\s+/g, " ");  const detectCase = (str: string): "camel" | "pascal" | "snake" | "kebab" | "unknown" => {    if (/^[a-z]+(?:[A-Z][a-z]*)*$/.test(str)) return "camel";    if (/^[A-Z][a-z]+(?:[A-Z][a-z]*)*$/.test(str)) return "pascal";    if (/^[a-z]+(?:_[a-z]+)*$/.test(str)) return "snake";    if (/^[a-z]+(?:-[a-z]+)*$/.test(str)) return "kebab";    return "unknown";  };  const convertCase = (str: string, format: "camel" | "pascal" | "snake" | "kebab"): string => {    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");    }  };  const currentCase = detectCase(str);  if (currentCase === targetFormat) {    return str;  // No conversion needed  }  const formatted = sanitiseString(str);  const words = formatted.split(/[-_ ]+/);  return convertCase(words.join(" "), targetFormat);};console.log(convertBetweenCases("random_variable_name", "camel"));  // Output: randomVariableNameconsole.log(convertBetweenCases("randomVariableName", "snake"));  // Output: random_variable_nameconsole.log(convertBetweenCases("random-variable-name", "pascal"));  // Output: RandomVariableNameconsole.log(convertBetweenCases("RandomVariableName", "kebab"));  // Output: random-variable-name

Here, we're putting everything we've discussed so far together, alongside some more Regex (in detectCase()) so that we can firstly identify the current case of the string being passed, before converting it.

This works like this:

  1. Sanitises Input

    : we use sanitiseString() to remove unwanted characters, trim whitespace, and normalise spacing.
  2. Detects Current Case

    : Calls detectCase() which determines the current case the string is in. If the string is already in the target format, it just returns.
  3. Handles Word Extraction

    : Splits the string into words using split(/[_ ]+/), which gives us the word structure we need to create our new case.
  4. Converts to Target Case

    : Calls convertCase() to transform the words into the specified format (camel, pascal, snake, or kebab).
  5. Returns Result

    : If the string is already in the target case, it returns it unchanged; otherwise, it returns the transformed string.

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 spaceseparated strings into camelCase, PascalCase, snake_case, and kebabcase whilst ensuring that the input is properly sanitised beforehand.

I've also bundled all of this together into a single utility function that can detect the case in a provided string, and then transform it into another.

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 (kebabcase) are widely used in APIs and URLs.
  • A robust utility function can detect and convert between different naming conventions dynamically.
  • 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.


Categories:

  1. Development
  2. Front‑End Development
  3. Guides
  4. JavaScript