Toolmingo
Guides5 min read

camelCase vs snake_case: A Guide to Text Case Conversion

Learn the difference between camelCase, snake_case, PascalCase, kebab-case, and SCREAMING_SNAKE_CASE. Includes when to use each, conversion rules, and code examples in JavaScript, Python, Go, and PHP.

camelCase vs snake_case: A Guide to Text Case Conversion

Every programming language, framework, and file-system has its own preferred naming style. Whether you're converting a variable name, renaming a file, or cleaning up an API response, understanding text case conventions saves time and prevents bugs.


The Five Most Common Cases

Case Example Also Called
camelCase myVariableName Lower camel case
PascalCase MyVariableName Upper camel case, StudlyCase
snake_case my_variable_name Underscore case
SCREAMING_SNAKE_CASE MY_VARIABLE_NAME Constant case, UPPER_SNAKE
kebab-case my-variable-name Lisp case, spinal case, slug case

There are also rarer variants like TRAIN-CASE (My-Variable-Name), dot.case (my.variable.name), and flatcase (myvariablename), but the five above cover 95% of real-world usage.


When to Use Each Case

camelCase

  • JavaScript / TypeScript: variables, function names, object keys
  • Java / Kotlin / Swift: variables, method names
  • JSON keys (by convention): {"firstName": "Ada"}
  • React props: onClick, isVisible, maxLength

PascalCase

  • Classes and types in most languages: UserAccount, HttpClient
  • React components: <MyButton />, <ProductCard />
  • C# / .NET: methods and properties use PascalCase, not camelCase
  • TypeScript interfaces and enums: interface ApiResponse, enum Status

snake_case

  • Python: the official PEP 8 style for variables and functions
  • Ruby: variables, methods, file names
  • PostgreSQL / MySQL: table names, column names (created_at, user_id)
  • PHP: older codebases and WordPress follow snake_case for functions

SCREAMING_SNAKE_CASE

  • Constants in most languages: MAX_RETRY_COUNT, API_BASE_URL
  • Environment variables: DATABASE_URL, NODE_ENV
  • Enum values in Go and C: STATUS_OK, HTTP_NOT_FOUND

kebab-case

  • HTML attributes: data-user-id, aria-label
  • CSS classes: .nav-bar, .hero-section
  • URL slugs and file names: how-to-use-regex.html, my-component.tsx
  • CLI flags: --dry-run, --output-format

The Conversion Algorithm

Any case-to-case conversion has two phases:

  1. Tokenise — split the input into words
  2. Rejoin — merge words in the target format

Phase 1: Tokenise

The trick is normalising all separators before splitting:

Input: "myVariableName" OR "my_variable_name" OR "my-variable-name"

Step 1 – insert underscore before each uppercase letter:
         "my_Variable_Name" (camelCase only)

Step 2 – replace hyphens, spaces, dots with underscores:
         "my_variable_name"

Step 3 – collapse repeated underscores → split on "_" → lowercase each word:
         ["my", "variable", "name"]

Phase 2: Rejoin

Target case Join rule
snake_case words.join("_")
SCREAMING_SNAKE_CASE words.join("_").toUpperCase()
kebab-case words.join("-")
camelCase first word lowercase, rest title-cased, no separator
PascalCase all words title-cased, no separator

Code Examples

JavaScript / TypeScript

function toWords(str) {
  return str
    .replace(/([a-z])([A-Z])/g, "$1_$2")   // split camelCase
    .replace(/[\s\-\.]+/g, "_")             // normalise separators
    .replace(/_+/g, "_")
    .toLowerCase()
    .split("_")
    .filter(Boolean);
}

const toSnake  = s => toWords(s).join("_");
const toScream = s => toWords(s).join("_").toUpperCase();
const toKebab  = s => toWords(s).join("-");
const toCamel  = s => toWords(s).map((w, i) => i === 0 ? w : w[0].toUpperCase() + w.slice(1)).join("");
const toPascal = s => toWords(s).map(w => w[0].toUpperCase() + w.slice(1)).join("");

console.log(toSnake("myVariableName"));   // "my_variable_name"
console.log(toCamel("my_variable_name")); // "myVariableName"
console.log(toPascal("kebab-case-str"));  // "KebabCaseStr"
console.log(toKebab("PascalCaseInput"));  // "pascal-case-input"

Python

import re

def to_words(s: str) -> list[str]:
    s = re.sub(r"([a-z])([A-Z])", r"\1_\2", s)   # split camelCase
    s = re.sub(r"[\s\-\.]", "_", s)               # normalise separators
    return [w for w in s.lower().split("_") if w]

def to_snake(s):  return "_".join(to_words(s))
def to_scream(s): return "_".join(to_words(s)).upper()
def to_kebab(s):  return "-".join(to_words(s))
def to_camel(s):  w = to_words(s); return w[0] + "".join(x.capitalize() for x in w[1:])
def to_pascal(s): return "".join(x.capitalize() for x in to_words(s))

print(to_snake("myVariableName"))    # my_variable_name
print(to_camel("my_variable_name"))  # myVariableName
print(to_pascal("kebab-case-str"))   # KebabCaseStr

Go

package main

import (
    "regexp"
    "strings"
)

var splitRe = regexp.MustCompile(`([a-z])([A-Z])`)
var sepRe   = regexp.MustCompile(`[\s\-\.]+`)

func toWords(s string) []string {
    s = splitRe.ReplaceAllString(s, "${1}_${2}")
    s = sepRe.ReplaceAllString(s, "_")
    s = strings.ToLower(s)
    parts := strings.Split(s, "_")
    out := parts[:0]
    for _, p := range parts {
        if p != "" { out = append(out, p) }
    }
    return out
}

func toSnake(s string) string  { return strings.Join(toWords(s), "_") }
func toScream(s string) string { return strings.ToUpper(strings.Join(toWords(s), "_")) }
func toKebab(s string) string  { return strings.Join(toWords(s), "-") }
func toCamel(s string) string {
    ws := toWords(s)
    for i := 1; i < len(ws); i++ {
        ws[i] = strings.Title(ws[i])
    }
    return strings.Join(ws, "")
}
func toPascal(s string) string {
    ws := toWords(s)
    for i, w := range ws { ws[i] = strings.Title(w) }
    return strings.Join(ws, "")
}

PHP

function to_words(string $s): array {
    $s = preg_replace('/([a-z])([A-Z])/', '$1_$2', $s);
    $s = preg_replace('/[\s\-\.]+/', '_', $s);
    return array_filter(explode('_', strtolower($s)));
}

function to_snake(string $s): string  { return implode('_', to_words($s)); }
function to_scream(string $s): string { return strtoupper(implode('_', to_words($s))); }
function to_kebab(string $s): string  { return implode('-', to_words($s)); }
function to_camel(string $s): string {
    $ws = array_values(to_words($s));
    return $ws[0] . implode('', array_map('ucfirst', array_slice($ws, 1)));
}
function to_pascal(string $s): string {
    return implode('', array_map('ucfirst', to_words($s)));
}

echo to_snake("myVariableName");  // my_variable_name
echo to_camel("my_variable_name"); // myVariableName

Quick Conversion Reference

Input → snake → SCREAM → kebab → camel → Pascal
helloWorld hello_world HELLO_WORLD hello-world helloWorld HelloWorld
my-component my_component MY_COMPONENT my-component myComponent MyComponent
USER_ID user_id USER_ID user-id userId UserId
GetHTTPResponse get_http_response GET_HTTP_RESPONSE get-http-response getHttpResponse GetHttpResponse

Edge Cases to Watch For

Acronyms — conventions differ:

  • Google/GitHub style: treat the whole acronym as one word → xmlParser, httpClient
  • Microsoft/.NET style: capitalise first letter only → XmlParser, HttpClient
  • Either is fine — just be consistent within a project.

Numbers — usually attached to the preceding word:

  • my2ndElement["my2nd", "element"] (most tokenisers)
  • Some tokenisers split at digit boundaries: my_2nd_element

Single-word inputs — no separators, no change needed. "hello""hello" in every case except PascalCase → "Hello" and SCREAMING → "HELLO".

Empty strings and null — always guard: if (!s) return s;


FAQ

Which case is "standard" for JSON?
No official standard, but camelCase is the most common in REST APIs (following JavaScript conventions). snake_case is used by GitHub, Stripe, and many Python APIs.

Does it matter which case I use?
Only within a codebase — mixed conventions are a red flag. Pick one per context (variables, files, URLs) and enforce it with a linter.

How do I enforce naming conventions automatically?
ESLint (camelcase rule), Prettier (limited), pylint, golangci-lint (revive), and most IDE code-style checkers all support naming rules.

Why is kebab-case invalid for JavaScript variable names?
The hyphen - is the subtraction operator in JavaScript, so my-variable is parsed as my minus variable. Use kebab-case only for CSS, HTML attributes, URLs, and file names.

What is Title Case?
Title Case capitalises the first letter of each word with spaces: "My Variable Name". Useful for UI labels and headings, not for code identifiers.

Related tools

Keep reading

All Toolmingotools are free & run in your browser

No sign-up, no upload, no watermark. Your files never leave your device.

Browse all tools