camelCase vs snake_case vs kebab-case
Every codebase has to pick how to glue multi-word names together — userId, user_id, or user-id? The choice is rarely free: each language community, file system, and protocol has a convention, and fighting it makes your code look foreign. This guide defines the five cases you will actually meet, shows where each one is the norm, and explains how to convert between them cleanly. When you just need to transform a list of names, the case converter does it instantly.
The Five Cases at a Glance
Almost every naming style you will meet is one of these five. The same three words — "user profile data" — written in each:
camelCase userProfileData first word lowercase, rest capitalized
PascalCase UserProfileData every word capitalized (UpperCamelCase)
snake_case user_profile_data lowercase, underscore-separated
kebab-case user-profile-data lowercase, hyphen-separated
SCREAMING_SNAKE_CASE USER_PROFILE_DATA uppercase, underscore-separated
They all encode the same information — the word boundaries — using different glue. The art is knowing which glue each context expects.
camelCase
The first word is lowercase; every subsequent word starts with a capital. It is the dominant convention for variables, functions, and object properties across the C family of languages:
let firstName = "Ada";
function parseQueryString(url) { /* ... */ }
const isLoggedIn = true;
- JavaScript / TypeScript — variables, functions, methods, object properties.
- Java, C#, Kotlin, Swift — methods and local variables (types use PascalCase).
- JSON — common for keys, especially in JavaScript-first and public APIs.
camelCase reads well in code but poorly in case-insensitive contexts, which is why you never see it in URLs or CSS.
PascalCase (UpperCamelCase)
Identical to camelCase except the first letter is also capitalized. It is reserved, by strong convention, for things that name a type rather than a value:
class UserAccount { /* ... */ }
interface HttpResponse { /* ... */ }
function UserProfileCard() { /* a React component */ }
- Classes, structs, interfaces, enums, and types in C#, Java, TypeScript, Swift, Go (for exported identifiers), and most others.
- React / Vue components — capitalization is how JSX distinguishes a component from an HTML tag.
- Namespaces and modules in many languages.
The camelCase-vs-PascalCase split inside one language is meaningful: userAccount is a variable, UserAccount is its type. Mixing them up reads as a mistake to anyone fluent in that ecosystem.
snake_case
Lowercase words joined by underscores. It is the native convention of several major languages and a frequent choice for data:
user_id = 42
def parse_query_string(url): ...
created_at = "2026-06-10"
- Python — variables, functions, and module names (PEP 8).
- Ruby — methods and variables.
- Rust — variables, functions, and modules.
- SQL — table and column names are conventionally snake_case (and case-insensitive without quoting).
- JSON — common for keys in APIs built on Python, Ruby, or Rails backends.
snake_case survives case-folding intact (the underscore is never altered), which makes it safer than camelCase for database columns and file names on case-insensitive file systems.
kebab-case
Lowercase words joined by hyphens. The underscore's twin, but used in a completely different set of places — mostly the web platform, where hyphens are the expected separator:
<div class="card-header">
background-color: #fff;
<user-profile-card></user-profile-card>
https://example.com/blog/how-to-name-things
- URLs and slugs — hyphens are treated as word separators by search engines, which helps SEO.
- CSS — class names by convention, and property names (
background-color) by requirement. - HTML attributes and custom elements — the spec requires a hyphen in custom-element names.
- npm package names and many CLI flags (
--dry-run).
Note that kebab-case is not a legal identifier in most programming languages, because the hyphen reads as a minus sign — user-id would parse as user minus id. That is precisely why it is confined to strings, markup, and configuration rather than code identifiers. For turning titles into kebab-case URLs, the slug generator handles the accents, punctuation, and spacing edge cases.
SCREAMING_SNAKE_CASE
Uppercase words joined by underscores. Universally understood to mean "this is a constant":
MAX_RETRIES = 5
const API_BASE_URL = "https://api.example.com";
DATABASE_URL=postgres://localhost/app # in a .env file
- Constants in Python, JavaScript, Java, C/C++ macros, and almost everywhere else.
- Environment variables — POSIX shells conventionally use uppercase exported names, so
.envfiles andprocess.env.API_KEYfollow suit. - Enum members in many languages.
The shouting is the point: the casing alone tells a reader the value is fixed at definition time and must not be reassigned.
How to Choose
You almost never get to pick freely — the context picks for you. The decision tree is short:
- Writing code? Follow the language's own convention. Python and Ruby want snake_case; JavaScript, Java, and C# want camelCase for values and PascalCase for types. Matching the ecosystem matters more than any personal preference.
- Naming a type, class, or component? PascalCase, in essentially every language that distinguishes types from values.
- A constant or environment variable? SCREAMING_SNAKE_CASE.
- A URL, CSS class, HTML attribute, or package name? kebab-case.
- A database column? snake_case, to avoid quoting and case-folding surprises.
- JSON keys? camelCase for JS-first APIs, snake_case for Python/Ruby-backed ones — but above all, be consistent across the whole API.
The one rule that overrides taste: be consistent within a boundary. A single API, file, or stylesheet that mixes conventions is harder to read than one that picks the "wrong" convention and sticks to it.
Converting Between Cases
Every conversion is the same two-step process: split the name into its words, then re-join them in the target style. The trick is splitting correctly, because the input style determines where the boundaries are:
- From camelCase / PascalCase: insert a boundary before each uppercase letter, then lowercase everything.
- From snake_case / SCREAMING_SNAKE_CASE: split on underscores.
- From kebab-case: split on hyphens.
Then re-join: underscores for snake_case, hyphens for kebab-case, capitalize-and-concatenate for camelCase and PascalCase. A naive regex handles the common path:
// camelCase -> kebab-case (handles the simple case)
"userProfileData".replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
// "user-profile-data"
# Python: snake_case -> camelCase
parts = "user_profile_data".split("_")
parts[0] + "".join(w.capitalize() for w in parts[1:])
# "userProfileData"
Where these one-liners fall down is on acronyms (parseHTMLResponse, userID) and embedded digits, where "before each uppercase letter" produces parse-h-t-m-l-response. Handling those correctly takes more logic than a single regex, which is why the case converter is the reliable way to transform a name or a whole list at once — it understands acronym and digit boundaries and outputs all five styles side by side.
Convert Names Instantly
Paste any identifier — or a whole column of them — into the case converter to see it in camelCase, PascalCase, snake_case, kebab-case, and SCREAMING_SNAKE_CASE at once. For turning article titles and headings into clean hyphenated URLs, the slug generator is the dedicated tool, and the JSON formatting best practices guide covers key-casing conventions for APIs in depth.
Frequently Asked Questions
What is the difference between camelCase and PascalCase?
Both join words by capitalizing each word's first letter and removing the separators, but they differ on the very first letter. camelCase leaves the first word lowercase (userId, parseHtml, isActive), while PascalCase, also called UpperCamelCase, capitalizes the first letter too (UserId, ParseHtml, IsActive). The convention in most C-family languages is camelCase for variables, functions, and methods, and PascalCase for types, classes, and components. So in JavaScript you write const userName but class UserAccount and function MyComponent for a React component.
Which case should I use for JSON keys?
There is no universal rule, so follow the ecosystem your API serves. Most public JSON APIs and JavaScript-first APIs use camelCase keys because they map naturally onto JavaScript object properties. Many APIs built on Python, Ruby, or Rails use snake_case keys to match those languages' conventions. Google's JSON Style Guide recommends camelCase. The most important rule is consistency, pick one convention for the whole API and never mix them, because clients deserialize keys literally and a single stray casing breaks the mapping.
Why are URLs and CSS written in kebab-case?
kebab-case (hyphen-separated lowercase) is the convention for URLs, CSS class names and properties, and HTML attributes for two practical reasons. First, these contexts are case-insensitive or case-folding, so camelCase would be unreliable, a URL path is commonly lowercased and snake_case underscores can be hidden by underlined links. Second, hyphens are treated as word separators by search engines and screen readers, which improves SEO and accessibility. CSS itself mandates kebab-case for property names like background-color, and HTML custom elements are required to contain a hyphen.
What is SCREAMING_SNAKE_CASE used for?
SCREAMING_SNAKE_CASE, uppercase words joined by underscores, is the near-universal convention for constants and environment variables. You see it in MAX_RETRIES, API_BASE_URL, and DATABASE_URL across almost every language, from C
How do I convert between camelCase, snake_case, and kebab-case?
The reliable approach is to first split the name into its component words, then re-join them in the target style. To split, insert a boundary before each uppercase letter (for camelCase and PascalCase input) and treat existing underscores or hyphens as boundaries, then lowercase everything. To re-join: snake_case joins with underscores, kebab-case joins with hyphens, camelCase capitalizes every word after the first and concatenates, and PascalCase capitalizes every word. The edge cases are acronyms like HTML or ID and digits, which is why a dedicated tool is more reliable than a one-line regex. The case converter handles all of these conversions at once.