Layerbit
Code Style

camelCase vs snake_case vs kebab-case: Naming Conventions by Language

Every language community settled on its own way of joining words into identifiers, and the style guides are explicit about it. Following them is not about taste: linters flag deviations, serializers depend on them, and a mismatch at a boundary, such as a JSON API in one style feeding a database in another, is a steady source of bugs. This is a reference to what each ecosystem expects, how acronyms are handled, and how to convert safely at the edges.

The short version

  • camelCase for variables and functions in JavaScript, TypeScript, Java, Kotlin and Swift; snake_case in Python, Ruby and Rust.
  • PascalCase for classes and types almost everywhere, and for all public members in C# and exported names in Go.
  • CONSTANT_CASE for constants and environment variables; kebab-case for URLs, CSS classes, file names and CLI flags.
  • Pick one acronym rule and apply it consistently: most modern style guides treat acronyms as words (XmlParser, userId); Go keeps them in capitals (userID).
  • Convert at the boundary with your serializer's naming policy, not by hand in business logic.

The styles, named

StyleExampleAlso called
camelCasecustomerOrderIdlower camel case, dromedary case
PascalCaseCustomerOrderIdupper camel case, StudlyCaps, CapWords
snake_casecustomer_order_idlower snake case
CONSTANT_CASECUSTOMER_ORDER_IDSCREAMING_SNAKE_CASE, upper snake case
kebab-casecustomer-order-iddash case, lisp case, spinal case
Train-CaseCustomer-Order-IdHTTP header case
dot.casecustomer.order.idused for configuration keys and log fields

Readability research is mixed: eye-tracking studies have found snake_case read slightly faster by some people and camelCase by others, mostly according to what they were used to. The practical argument is consistency. A codebase where every name follows the ecosystem's convention is easier to search, easier to review, and works with the tools that assume it.

By language

LanguageVariables & functionsTypes & classesConstantsSource
Pythonsnake_casePascalCaseCONSTANT_CASEPEP 8
JavaScript / TypeScriptcamelCasePascalCaseCONSTANT_CASE or camelCaseCommon practice, Google style guides
Java / KotlincamelCasePascalCaseCONSTANT_CASEJava conventions, Google Java Style
C#camelCase locals and parameters; PascalCase methods and propertiesPascalCase, interfaces prefixed IPascalCase.NET design guidelines
GocamelCase unexported, PascalCase exportedsame rulesame ruleEffective Go
Rustsnake_casePascalCaseCONSTANT_CASERust API guidelines (RFC 430)
Rubysnake_casePascalCaseCONSTANT_CASERuby style guide
PHPcamelCase methodsPascalCaseCONSTANT_CASEPSR-1
SwiftcamelCasePascalCasecamelCaseSwift API design guidelines

In Go the case is not just style: a name that starts with a capital letter is exported from its package, and one that starts with a lower-case letter is private, so renaming a function from parseConfig to ParseConfig changes its visibility. In C#, the .NET guidelines put public members in PascalCase, and the runtime's own code base uses _camelCase for private fields.

Outside the code: data, URLs and infrastructure

  • SQL. Use snake_case for tables and columns. PostgreSQL folds unquoted identifiers to lower case, so a column created as "orderId" must be quoted in every query forever after, while order_id never needs quotes.
  • JSON APIs. Both camelCase (Google's JSON style guide, most JavaScript-first APIs) and snake_case (GitHub, Stripe, Slack) are common. Choose one per API and never mix them within a payload.
  • URLs. Use lowercase kebab-case slugs. Google's own guidance recommends hyphens rather than underscores to separate words in URLs, and lower case avoids duplicate addresses on case-sensitive servers.
  • CSS. Class names and custom properties are conventionally kebab-case (.card-header, --brand-text); the BEM methodology adds block__element--modifier.
  • Environment variables. CONSTANT_CASE, such as DATABASE_URL, by universal convention and because many shells do not accept hyphens in variable names.
  • HTTP headers. Written in Train-Case by convention (Content-Type), but header names are case-insensitive, and HTTP/2 and HTTP/3 transmit them in lower case. Never compare header names case-sensitively.
  • Files and packages. Kebab-case for web assets and npm packages, which must be lower case; snake_case for Python modules, which cannot contain hyphens because the file name becomes the import name.

Acronyms and initialisms

The hardest case in camelCase and PascalCase is a name that contains an acronym. There are two schools. One keeps acronyms in capitals: XMLHttpRequest, userID, ServeHTTP. Go's code review guidelines require this, and some browser APIs follow it. The other treats an acronym as an ordinary word: XmlHttpRequest, userId, HtmlParser. Google's Java and JavaScript style guides, the Rust API guidelines and most modern codebases prefer this, because consecutive capitals make word boundaries ambiguous: is HTTPSURL "HTTPS URL" or "HTTP SURL"? The .NET guidelines split the difference, keeping two-letter acronyms in capitals (IOStream) and treating longer ones as words (XmlReader).

Whichever rule a project follows, conversion tools need to understand both. A good converter splits XMLHttpRequest into XML · Http · Request and getUserID2FA into get · User · ID · 2 · FA, so that the snake_case form is xml_http_request rather than x_m_l_http_request.

Converting at the boundary

When data crosses from one convention to another, convert once, at the edge, with the serializer's built-in naming policy. Hand-written mapping code drifts out of date the first time someone adds a field. Most ecosystems support it directly:

# Python, Pydantic v2: snake_case fields, camelCase JSON
class Order(BaseModel):
    model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)
    order_id: int

// Java, Jackson: camelCase fields, snake_case JSON
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
class Order { long orderId; }

// C#, System.Text.Json: PascalCase properties, camelCase JSON
new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };

// Rust, serde
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct Order { order_id: u64 }

For one-off jobs, such as renaming a column list, generating constants from a spreadsheet header or turning a page title into a URL slug, a converter that works line by line is faster. Our text case converter converts a pasted list of names into seventeen styles at once and handles acronyms and digits the way described above.

Convert names between conventions camelCase, PascalCase, snake_case, CONSTANT_CASE, kebab-case, Train-Case, dot.case, title case and URL slugs, line by line, with acronym-aware word splitting. Runs in your browser.
Open the text case converter

Frequently asked questions

Only the first letter. camelCase starts in lower case and capitalises each following word, as in orderTotal; PascalCase capitalises every word including the first, as in OrderTotal. Most languages use camelCase for variables and functions and PascalCase for classes and types. C# also uses PascalCase for methods and properties, and Go uses it to mark a name as exported.

Either is acceptable, as long as an API uses one style throughout. camelCase matches JavaScript clients and Google's JSON style guide; snake_case matches Python and Ruby backends and is used by APIs such as GitHub and Stripe. Pick the one that matches most of your consumers, document it, and let the serializer convert to your server's internal style.

PEP 8, Python's style guide, uses snake_case for functions, variables, methods and module names, PascalCase (which it calls CapWords) for classes and exceptions, and CONSTANT_CASE for module-level constants. A single leading underscore marks a name as internal, and a double leading underscore triggers name mangling inside classes.

Hyphens. Google's URL structure guidance recommends hyphens to separate words because search engines treat a hyphen as a word separator, while an underscore may join words together. Use lower case as well, since paths are case-sensitive on most servers and mixed case creates duplicate addresses for the same page.

Follow your language's style guide. Go keeps acronyms in capitals, as in userID and ServeHTTP. Google's Java and JavaScript guides and the Rust guidelines treat them as words, as in userId and XmlParser, which keeps word boundaries readable. .NET keeps two-letter acronyms capitalised and treats longer ones as words. Consistency within a codebase matters more than which rule you choose.