camelCase, snake_case, kebab-case: Naming Conventions Across Languages

Which casing style each language and ecosystem expects, why it matters for APIs and URLs, and how to convert between styles without mangling acronyms.

Every programming ecosystem has opinions about how to write multi-word names. Python wants user_name, JavaScript wants userName, C# wants UserName for most public members, CSS wants user-name, and environment variables want USER_NAME. None of these is more correct than the others. What matters is following the convention of the place the name lives, and converting cleanly at the boundaries.

This guide maps the conventions to the ecosystems that use them, explains where they came from, and covers the tricky parts of converting between them. The Case Converter handles the mechanical part.

The styles

StyleExampleAlso called
camelCaseorderTotallower camel case, dromedary case
PascalCaseOrderTotalupper camel case
snake_caseorder_total
SCREAMING_SNAKE_CASEORDER_TOTALconstant case
kebab-caseorder-totaldash case, lisp case
Title CaseOrder Total

Where each one comes from

snake_case has roots in C and Unix, where standard library names like str_len style identifiers and lower-case conventions were common. Python formalized it in PEP 8, which recommends snake_case for functions and variables. Ruby, Rust (for functions and variables) and most SQL schemas use it too.

camelCase was popularized by Smalltalk in the 1970s and 80s and inherited by Java and then JavaScript. JavaScript's own APIs use it throughout: getElementById, addEventListener, toLowerCase.

PascalCase takes its name from the Pascal language and its descendants. Today it is the near-universal convention for types: classes in Java, TypeScript, Python and C#, React components, and Go's exported identifiers (where an initial capital literally changes visibility).

kebab-case goes back to Lisp, where hyphens are legal in identifiers. Most C-family languages cannot use it for variable names, because order-total parses as subtraction, so it lives where names are strings: CSS properties and class names, HTML attributes, command-line flags like --dry-run, npm package names and URLs.

SCREAMING_SNAKE_CASE marks constants in many languages and is the standard for environment variables, partly because shells traditionally treat them case-sensitively and upper case makes them stand out.

By ecosystem

ContextVariables / functionsTypes / classesConstants
JavaScript / TypeScriptcamelCasePascalCaseUPPER_SNAKE or camelCase
Pythonsnake_casePascalCaseUPPER_SNAKE
JavacamelCasePascalCaseUPPER_SNAKE
C#camelCase (locals), PascalCase (public members)PascalCasePascalCase
GocamelCase (unexported), PascalCase (exported)same rulesame rule
Rubysnake_casePascalCaseUPPER_SNAKE
Rustsnake_casePascalCaseUPPER_SNAKE
SQLsnake_case for tables and columns (common)
CSS / HTMLkebab-case
URLskebab-case

Why it matters at boundaries

Conventions mostly cause friction where two ecosystems meet.

APIs. A Python or Ruby backend naturally produces created_at. A JavaScript frontend naturally wants createdAt. Teams have to choose: convert in the API layer, convert in the client, or accept snake_case in JavaScript. Google's JSON style guide recommends camelCase for JSON property names; many Rails and Django APIs use snake_case. Whichever you choose, choose once and document it.

Databases. PostgreSQL folds unquoted identifiers to lower case, so a column created as createdAt without quotes becomes createdat. Using snake_case in SQL avoids having to quote every identifier forever.

URLs. Google's URL guidance recommends hyphens to separate words, so /order-history rather than /order_history or /orderHistory. See the URL slug guide.

Files. Some file systems are case-insensitive (macOS and Windows by default) and some are not (Linux). Renaming userCard.tsx to UserCard.tsx can confuse Git on a Mac and break the build on a Linux CI server. Many teams use kebab-case for filenames to sidestep the problem.

The hard part: acronyms and word boundaries

Converting userName to user_name is easy: split before capitals. Real names are messier.

Acronyms. Is it XMLHttpRequest, XmlHttpRequest or xmlHTTPRequest? The browser API itself mixes styles. Style guides disagree:

  • Microsoft's .NET guidelines keep two-letter acronyms upper case (IOStream) and capitalize only the first letter of longer ones (XmlReader).
  • Google's Java style guide treats acronyms as words: XmlHttpRequest, customerId.
  • Go's convention keeps initialisms consistently cased: userID, HTTPServer.

An automatic converter splitting on capitals turns parseHTMLString into something like parse_h_t_m_l_string or parse_htmlstring depending on its rules. Always check acronyms after converting.

Numbers. Should address2 become address_2 or stay address2? Should utf8 become utf_8? There is no universal answer.

Non-ASCII text. Converters that rely on ASCII patterns may drop or mishandle accented letters.

Converting safely

  1. Convert, then read the result. Pay special attention to acronyms and numbers.
  2. For bulk renames in code, use your IDE's rename refactoring rather than search-and-replace, so references are updated too.
  3. For API payloads, convert at a single, well-tested layer, for example a serializer, rather than ad hoc throughout the code.
  4. Add a linter rule (ESLint's camelcase, Pylint's naming checks, RuboCop) so new code follows the convention automatically.

Title case is its own topic

The converter's Title option capitalizes the first letter of every word. Editorial styles are more nuanced: AP, Chicago and APA all keep short articles, conjunctions and prepositions such as "of", "and" and "the" in lower case unless they start the title, and they disagree on details such as prepositions of four or more letters. For headlines, use the converter as a first pass and then apply your publication's style.

Related tools

Launch Case Converter