Developer Guides

camelCase vs snake_case vs kebab-case: Naming Conventions

camelCase, snake_case, PascalCase and kebab-case each have a home. Here's which style each language and format expects, and how to convert at the boundaries.

  • By Jacob
  • 6 min read
Rows of small blue blocks joined in different ways, suggesting different naming styles such as camelCase, snake_case and kebab-case

userProfileId, user_profile_id, user-profile-id, UserProfileId, USER_PROFILE_ID. Same three words, five spellings, and every one of them is "correct" somewhere. Which one you use depends on the language, the kind of name, and sometimes the tool that will read it.

Here's what each style is called, where it's the standard, and what to do at the boundaries where two conventions meet, like a Python backend serving a JavaScript frontend.

The five common styles

StyleExampleAlso called
camelCaseuserProfileIdlower camel case, mixedCase
PascalCaseUserProfileIdupper camel case, CapWords
snake_caseuser_profile_id
SCREAMING_SNAKE_CASEUSER_PROFILE_IDconstant case, upper snake case
kebab-caseuser-profile-iddash case, spinal case

Our Case Converter converts between all of these. It splits words at spaces, underscores, hyphens and capital letters, so parseHTTPResponse becomes parse_http_response, parse-http-response or PARSE_HTTP_RESPONSE, and XMLHttpRequest becomes xml_http_request.

Conventions by language

Most languages have an official or dominant style guide. The table below follows them:

LanguageVariables and functionsClasses and typesConstants
Pythonsnake_casePascalCaseSCREAMING_SNAKE_CASE
JavaScript / TypeScriptcamelCasePascalCaseSCREAMING_SNAKE_CASE
JavacamelCasePascalCaseSCREAMING_SNAKE_CASE
C#camelCase (locals, parameters), PascalCase (methods, public members)PascalCasePascalCase
GocamelCase, or PascalCase if exportedPascalCase if exportedSame as other names
Rustsnake_casePascalCaseSCREAMING_SNAKE_CASE
Rubysnake_casePascalCaseSCREAMING_SNAKE_CASE
PHPcamelCase (PSR-1 methods)PascalCaseSCREAMING_SNAKE_CASE

A few details from the source documents:

  • Python: PEP 8 says function names "should be lowercase, with words separated by underscores," classes use "the CapWords convention," and constants are "written in all capital letters with underscores separating words." It allows mixedCase "only in contexts where that's already the prevailing style."
  • Go: Effective Go says "the convention in Go is to use MixedCaps or mixedCaps rather than underscores." In Go, case is also visibility: "the visibility of a name outside a package is determined by whether its first character is upper case." So Owner is exported and owner isn't.
  • Rust: the Rust API guidelines use snake_case for functions, methods, variables and modules, UpperCamelCase for types and traits, and SCREAMING_SNAKE_CASE for constants and statics. The compiler warns when you don't.
  • C#: Microsoft's naming conventions use PascalCase for types, methods and public members, camelCase for parameters and locals, an _ prefix for private fields, and an I prefix for interfaces.

Acronyms: HTTPServer or HttpServer?

Style guides disagree here, so it's worth picking a rule. The Rust guidelines are explicit: "acronyms and contractions of compound words count as one word: use Uuid rather than UUID." Many JavaScript, Java and C# codebases follow the same rule (HttpClient, JsonParser), because XMLHTTPRequest makes it impossible to see where words start. Go goes the other way and keeps acronyms in one case, as in ServeHTTP and userID.

Whatever you choose, apply it everywhere. A converter can split HTTPServer correctly, but people reading getHTTPSURLForAPI can't.

kebab-case: the web's style

Hyphens can't appear in identifiers in most programming languages, because user-id reads as "user minus id." But kebab-case is the norm wherever names are plain text rather than code:

  • URLs. Google's URL structure guidelines recommend "using hyphens (-) instead of underscores (_) to separate words in your URLs." Our Text to Slug tool turns titles into lowercase, hyphenated slugs.
  • CSS. Properties (font-size), custom properties (--brand-color) and most class naming systems use hyphens.
  • HTML attributes. Custom data attributes are written data-user-id. In JavaScript, the browser exposes them through dataset in camelCase, so data-user-id becomes element.dataset.userId. It's a built-in example of converting between two conventions.
  • File names, command-line flags and package names in many ecosystems, such as --dry-run or npm packages.

Where conventions meet

The hard cases are boundaries between systems with different habits.

JSON APIs

There's no single rule. Many APIs use camelCase keys because JavaScript clients consume them directly. Many others, including the GitHub and Stripe APIs, use snake_case keys like created_at. Pick one for your whole API and document it. Then let each side convert at the edge: a Python backend can keep snake_case internally and serialize to camelCase, or a JavaScript client can map snake_case responses to camelCase objects. Don't mix styles inside one payload.

Databases

snake_case is the common choice for table and column names, and in PostgreSQL there's a practical reason. Its documentation explains that unquoted identifiers are folded to lowercase, so a column created as userId becomes userid, and keeping the capital means quoting the name in every query. user_id avoids the problem.

Environment variables

By long convention, environment variables are SCREAMING_SNAKE_CASE: DATABASE_URL, NODE_ENV. Configuration libraries often map them to camelCase or snake_case properties in code.

Converting names in code

At API boundaries you often need to convert keys programmatically. The common one-line regex for camelCase to snake_case breaks on acronyms:

# Python: the naive version
re.sub(r'(?<!^)(?=[A-Z])', '_', 'parseHTTPResponse').lower()
# → 'parse_h_t_t_p_response'

Splitting in two steps, first between an acronym and the next word, then between a lowercase letter or digit and a capital, handles both cases. This is the same approach the Case Converter uses:

def to_snake(name):
    name = re.sub(r'([A-Z])([A-Z][a-z])', r'\1_\2', name)
    name = re.sub(r'([a-z0-9])([A-Z])', r'\1_\2', name)
    return name.lower()

to_snake('parseHTTPResponse')  # 'parse_http_response'
to_snake('XMLHttpRequest')     # 'xml_http_request'

Going the other way is simpler. In JavaScript:

const toCamel = (s) => s.replace(/_([a-z0-9])/g, (_, c) => c.toUpperCase());

toCamel('created_at');  // 'createdAt'

Note that conversions aren't always reversible. user_id becomes userId, which converts back to user_id, but userID becomes user_id and comes back as userId. Test round trips if both sides depend on exact names.

Common naming mistakes

  • Mixing styles in one place. A JSON object with userId, created_at and Last-Modified keys forces every consumer to remember three rules.
  • Abbreviating inconsistently. usr, user and u for the same thing are worse than any casing choice. Microsoft's guidelines put it simply: "Prefer clarity over brevity."
  • Relying on case alone to tell names apart. data and Data in the same scope are legal in many languages and confusing in all of them.
  • Using kebab-case where code reads the names. A JSON key like user-id works, but in JavaScript it can only be read as obj["user-id"], not obj.user-id.

Choosing a style for your project

  1. Follow the language's style guide for code. Readers, linters and libraries all expect it.
  2. Follow the target format's convention for everything else: kebab-case for URLs and CSS, snake_case or the project's choice for database columns and JSON.
  3. Convert at the boundaries, in one place, rather than letting styles leak through the codebase.
  4. Automate it. Linters like ESLint, Pylint, RuboCop and Clippy can enforce naming rules, so reviews don't have to.

PEP 8 sums up the priority well: "Consistency with this style guide is important. Consistency within a project is more important."

FAQ

Is camelCase or snake_case easier to read?

Studies have reached different conclusions, and familiarity seems to matter more than the style itself. Use what your language's community uses.

What's the difference between camelCase and PascalCase?

Only the first letter. camelCase starts lowercase (userName), PascalCase starts uppercase (UserName). Many languages use PascalCase for types and camelCase for variables.

Should URLs use underscores or hyphens?

Hyphens, per Google's guidelines. Keep them lowercase too, since Google treats URL paths as case-sensitive.

How do I convert a whole list of names at once?

Paste one name per line into the Case Converter. Each line is converted separately, so you can turn a column of database fields into camelCase properties in one step.