Menu

camelCase vs snake_case vs kebab-case vs PascalCase: Naming Conventions Explained

All four join several words into one name without spaces. camelCase (userFirstName) and PascalCase (UserFirstName) use capital letters, snake_case (user_first_name) uses underscores and kebab-case (user-first-name) uses hyphens. Which one is right depends on the language and on what you are naming.

Published

camelCase, snake_case, kebab-case and PascalCase are four ways to write a multi-word name where spaces are not allowed. They differ in one thing: how the word boundary is marked. camelCase and PascalCase mark it with a capital letter, snake_case with an underscore and kebab-case with a hyphen. No style is better than the others; each one belongs to certain languages and kinds of names, and the rule that matters is to follow the convention of the place you are writing in. To convert a list of names, paste it into the camelCase converter, snake_case converter, kebab-case converter or PascalCase converter.

The four styles side by side

The phrase “user first name” in each style, plus the two variants people usually need next:

Style Example Word boundary First letter Also called
camelCase userFirstName capital letter lowercase lowerCamelCase
PascalCase UserFirstName capital letter uppercase UpperCamelCase, CapWords
snake_case user_first_name underscore lowercase
SCREAMING_SNAKE_CASE USER_FIRST_NAME underscore uppercase (all) CONSTANT_CASE
kebab-case user-first-name hyphen lowercase
dot.case user.first.name period lowercase

Each style has a practical trade-off:

  • camelCase and PascalCase are the shortest, because the boundary costs no character. They get harder to read when acronyms meet (XMLHTTPRequest), which is why several style guides have rules for acronyms (see below).
  • snake_case keeps every word lowercase and separate, so it reads a lot like normal text. It works almost everywhere, since the underscore is a valid identifier character in nearly every programming language.
  • kebab-case reads like snake_case but cannot be a variable name in most languages, where user-first-name means “user minus first minus name”. It is used where names are plain strings: CSS, HTML, file names, command-line flags and URLs.

Which languages and tools use which

These are the conventions in the official or most widely used style guide for each language. They are conventions, not compiler rules (Go is the exception noted below).

Language or place Variables and functions Classes and types Constants Source
Python snake_case PascalCase (“CapWords”) SCREAMING_SNAKE_CASE PEP 8
JavaScript / TypeScript camelCase PascalCase CONSTANT_CASE Google JavaScript Style Guide
C# / .NET camelCase for locals and parameters; PascalCase for methods and public members PascalCase PascalCase Microsoft Learn
Go mixedCaps (unexported) or MixedCaps (exported) MixedCaps MixedCaps Effective Go
Rust snake_case UpperCamelCase SCREAMING_SNAKE_CASE Rust API Guidelines
CSS kebab-case properties and custom properties (--first-color) MDN

A few details worth knowing:

  • Python packages and modules are all lowercase. PEP 8 allows underscores in module names “if it improves readability” but discourages them in package names.
  • C# in Microsoft’s conventions also prefixes private and internal fields with an underscore (_workerQueue) and private static fields with s_, so a C# file often mixes three patterns on purpose.
  • Go is the one place where case changes behavior: Effective Go states that “the visibility of a name outside a package is determined by whether its first character is upper case.” Renaming orderTotal to OrderTotal exports it. Go uses MixedCaps “rather than underscores” for multi-word names.
  • CSS and JavaScript meet in the DOM. MDN notes that the style object has both dash-named and camel-case named properties for every CSS property, so border-top in a stylesheet is borderTop in JavaScript. The kebab-case converter turns backgroundColor into background-color, and the camelCase converter turns border-top into borderTop.
  • CSS custom properties are case sensitive: MDN points out that --my-color and --My-color are two different properties, one more reason to keep CSS names all lowercase.

For JSON keys, database columns and API fields there is no single standard. Python and SQL projects lean toward snake_case and JavaScript projects toward camelCase, but the API you are calling decides. Check its documentation and copy what it uses.

Hyphens or underscores in URLs and file names

For web addresses the answer is clear. Google Search Central recommends “using hyphens (-) instead of underscores (_) to separate words in your URLs”, because underscores are used in programming to join concepts (its example is format_date) “whereas hyphens clearly signal a word boundary.” Its recommended example is summer-clothing, not summer_clothing.

So a page about naming conventions would live at /blog/naming-conventions, a kebab-case slug. For URLs, use the text to slug converter rather than the kebab-case one: it removes accents and apostrophes and keeps only ASCII letters and digits (Café Menu: Naming Conventions! becomes cafe-menu-naming-conventions), while the kebab-case tool keeps letters such as é as they are. The guide what is a URL slug explains the rest.

File names are less strict. Google’s JavaScript style guide allows lowercase file names with “underscores (_) or dashes (-), but no additional punctuation.” Pick one per project and stick to it.

Acronyms and numbers

Acronyms are where the styles disagree most. Is it XMLHttpRequest, XmlHttpRequest or XMLHTTPRequest? The guides that address it treat an acronym as an ordinary word:

  • Google’s JavaScript style guide lowercases everything, acronyms included, and then capitalizes the first letter of each word. Its examples: “XML HTTP request” becomes xmlHttpRequest, not XMLHTTPRequest, and “new customer ID” becomes newCustomerId, not newCustomerID.
  • The Rust API Guidelines say acronyms “count as one word: use Uuid rather than UUID”.

Our converters follow the same approach. They split a word where a lowercase letter or digit meets a capital, and where a run of capitals meets a capitalized word (the L and H in XMLHttp), then rebuild the name:

Input camelCase PascalCase snake_case kebab-case
get HTTP response code getHttpResponseCode GetHttpResponseCode get_http_response_code get-http-response-code
XMLHttpRequest xmlHttpRequest XmlHttpRequest xml_http_request xml-http-request
new customer ID newCustomerId NewCustomerId new_customer_id new-customer-id
Is-Valid email address isValidEmailAddress IsValidEmailAddress is_valid_email_address is-valid-email-address
order 2 items order2Items Order2Items order_2_items order-2-items
version2Update version2Update Version2Update version2_update version2-update

Two things to notice. Converting to snake_case or kebab-case loses the original capitals, so XMLHttpRequest cannot come back from xml_http_request: converting it to PascalCase gives XmlHttpRequest. And a digit stays attached to the word before it unless there was a space (version2Update keeps version2 together).

Words like IPv6 and iOS are kept whole: supports IPv6 on iOS becomes supportsIpv6OnIos in camelCase and supports_ipv6_on_ios in snake_case, as the Google guide expects. Apostrophes inside a word are removed before splitting, which is also the first step of Google’s procedure, so Don't stop becomes dontStop and dont_stop. Brand names shaped like iPhone are still split at the capital (iPhone app becomes i_phone_app), because identifiers such as xAxis have the same shape, so check those by hand.

Converting a list of names

Renaming JSON keys to match a Python model, turning CSS property names into JavaScript style names, or producing constant names from a spreadsheet column all work the same way:

  1. Paste the names into the camelCase, snake_case, kebab-case or PascalCase converter linked at the top of this guide, one name per line. The input can be in any style, including plain words with spaces.
  2. Choose the Style option if you need the variant: the camelCase and PascalCase tools switch between the two, the snake_case tool offers SCREAMING_SNAKE_CASE, and the kebab-case tool’s Separator option offers dot.case.
  3. Copy the result. Each line is converted on its own and empty lines stay in place, so the output lines up with the input row by row.

The tools treat any character that is not a letter or digit (spaces, hyphens, underscores, periods, slashes) as a word break and drop it; apostrophes inside a word are simply removed. Leading and trailing spaces disappear, and user.first-name_v2 becomes userFirstNameV2. The one exception is underscores at the start or end of a line in snake_case and SCREAMING_SNAKE_CASE, which are kept because they carry meaning in Python (_private_var and __init__ stay as they are); the other styles drop them. Accented letters are kept, which is fine in most modern languages but not in identifiers restricted to ASCII. For running text rather than identifiers, the case converter handles title case, sentence case and the rest.

How to choose

When the decision is yours, these rules cover most situations:

  • Inside code, use what the language’s style guide says (the table above). Use camelCase for JavaScript variables and snake_case for Python and Rust functions, without debating it.
  • For types and classes, PascalCase is close to universal across these languages.
  • For constants and environment variables, SCREAMING_SNAKE_CASE.
  • For URLs, CSS class names and command-line options, kebab-case.
  • For data that crosses systems (JSON, CSV headers, database columns), follow the system you are talking to; if you own it, pick one style and write it down.

Consistency matters more than the choice itself. A codebase that uses user_id in one file and userId in the next makes every name a small guessing game.

Questions

Is camelCase or snake_case better?

Neither is better in general. Follow the convention of the language or project you are working in, snake_case for Python functions and variables (PEP 8), lowerCamelCase for JavaScript variables (Google's style guide), because mixed styles in one codebase are harder to read than either style on its own.

What is the difference between camelCase and PascalCase?

Only the first letter. camelCase starts lowercase (orderTotal), PascalCase starts uppercase (OrderTotal). Google's style guides call them lowerCamelCase and UpperCamelCase, and PEP 8 calls PascalCase "CapWords".

Why can't I use kebab-case for variable names?

In most programming languages the hyphen is the minus operator, so user-name would be read as user minus name. kebab-case lives where names are plain text, such as CSS properties, HTML attributes, file names and URLs.

What is SCREAMING_SNAKE_CASE?

snake_case in capital letters, such as MAX_RETRY_COUNT. PEP 8, the Rust API Guidelines and Google's JavaScript style guide (which calls it CONSTANT_CASE) all use it for constants. The snake_case converter has it as a style option.

Should URLs use hyphens or underscores?

Hyphens. Google Search Central recommends hyphens instead of underscores in URLs because hyphens clearly mark a word boundary. The guide what is a URL slug covers the other slug rules.

Sources