Home · Blog · Text

Case styles explained: camelCase, snake_case, kebab-case and when each belongs

Every identifier, URL and headline wears a case style, and each community has strong opinions about which. This field guide defines the eleven styles you will actually meet, shows how acronyms and numbers strain them, and matches styles to the places they are conventional — so you can convert confidently instead of guessing.

Case is information. user_id, userId and user-id contain the same two words, yet each announces a different world — a database or Python file, a JavaScript codebase, a URL or CSS class. Programmers read these styles as fluently as punctuation, and using the wrong one in the wrong place is a small but constant friction: style linters complain, URLs look alien, and screen readers stumble.

Below are the styles that matter, precise definitions of each, the messy corners (acronyms, leading numbers, mixed conventions), and a matching guide that reflects what each community actually does — as opposed to what individual taste prefers.

Key takeaways

  • The four workhorses: camelCase, PascalCase, snake_case, kebab-case. Everything else is a variation or a headline style.
  • Acronyms are the eternal edge case: pick the HTTPServer or HttpServer convention once per project and never improvise.
  • URLs and CSS belong in kebab-case; most languages reserve hyphens for subtraction, which is exactly why kebab cannot appear in identifiers.
  • Sentence case has quietly won the headline wars; Title Case survives in defined house styles and US publishing.

The styles, defined on one phrase

Using "user profile image" as raw material:

StyleRenderedNative habitat
camelCaseuserProfileImageVariables and functions in JavaScript, Java, Swift, Go (exported names differ)
PascalCaseUserProfileImageClasses and types almost everywhere; C# methods; React components
snake_caseuser_profile_imagePython, Ruby, Rust variables; database columns; file names in data pipelines
SCREAMING_SNAKE_CASEUSER_PROFILE_IMAGEConstants in most languages; environment variables
kebab-caseuser-profile-imageURLs, CSS classes, HTML attributes, CLI flags (--user-profile)
Train-CaseUser-Profile-ImageHTTP headers (User-Agent, Content-Type); some title systems
flatcaseuserprofileimagePackage names, hashtags, legacy systems; readability suffers beyond two words
Title CaseUser Profile ImageHeadlines and book titles under AP/Chicago-style rules
Sentence caseUser profile imageModern UI labels, most web headlines, documentation headings

Two of these are not identifier styles at all — Title and Sentence case contain spaces and belong to prose — but they belong in the same conversation because converters, CMSs and style guides constantly translate between all eleven.

Acronyms, numbers and other fault lines

Acronyms expose every style's weakness. Is it parseHTTPResponse or parseHttpResponse? Languages with strong conventions answer for you (Go: initialisms stay uniform — HTTPServer, serveHTTP; .NET: two-letter acronyms capitalised, longer ones Pascal-cased). Projects without a ruling drift into all three forms at once, which is worse than any single choice: search stops working, and reviewers argue the same point forever. Numbers behave similarly: oauth2Token and version3Id are readable, but a digit must never lead an identifier in most languages, so 3dModel becomes model3d or threeDModel by team convention.

Plurals and boundaries create the last class of ambiguity: userIDs versus userIds, login as one word versus logIn. A converter applies one consistent splitting rule; a style guide records the exceptions. Both beat memory.

Matching style to place: the conventions that are actually load-bearing

  • URLs: lowercase kebab-case. Case-sensitive servers and filesystems exist, users type URLs from memory, and search engines treat hyphens as word separators while underscores glue words together.
  • Databases: snake_case for tables and columns survives every ORM and query tool without quoting; mixedCase column names become a lifetime of double quotes in Postgres.
  • Environment variables and shell: SCREAMING_SNAKE_CASE, because lowercase names collide with ordinary shell variables and POSIX reserves the uppercase space for the system.
  • CSS: kebab-case classes by near-universal custom (BEM builds whole methodologies on it).
  • Code: follow the language, not your taste — fighting a language's convention means fighting its standard library in every file.
  • Accessibility note: screen readers handle camelCase surprisingly well (they split on capitals), hyphenated and underscored text less consistently, and flatcase worst of all — one more argument against running words together in anything users will hear read aloud.

Converting without corrupting

Conversion looks mechanical and hides three traps. First, splitting: a converter must decide whether XMLHttpRequest is xml-http-request or x-m-l-http-request — splitting on capital runs, not single capitals. Second, information loss is one-directional: camelCase to snake_case is lossless, but sentence case to camelCase cannot recover which words were acronyms or proper nouns. Third, converting identifiers in live systems is a rename, not a reformat — URLs change (breaking links), database columns change (breaking queries), API fields change (breaking clients). Convert at creation; in established systems, convert the style guide and the new code, and leave the old names standing.

Mistakes and pitfalls

Mixing styles inside one layer

A codebase with getUser, fetch_user and load-user in adjacent files forces readers to remember three systems. Consistency within a layer matters more than which system the layer chose.

Using underscores in URLs because the codebase uses snake_case

URL conventions answer to the web, not to your backend. Underscores in paths are read by search engines as joining characters, and they disappear visually when a URL is underlined as a link.

Title-Casing everything for importance

Title Case applied to buttons, labels and headings at random makes interfaces shout and dates the design instantly. Follow a stated house style — which, for most product UI today, is sentence case.

Common questions

Is SCREAMING_SNAKE_CASE really necessary for constants?

Only where convention says so — but it says so in a lot of places (environment variables above all). In languages with a real const keyword and a calmer house style, the screaming is optional; in shell and config, it is protective.

Why is kebab-case illegal in most programming languages?

Because the hyphen is the minus operator: user-id parses as user minus id. That single fact of grammar is why the identifier world split into underscores and capitals, and why kebab retreated to the places — URLs, CSS, flags — where no subtraction exists.

What should file names use?

Lowercase kebab-case or snake_case, consistently; avoid spaces and capitals, which invite URL-encoding and case-sensitivity bugs when files move between systems. Data pipelines lean snake, web assets lean kebab — either beats "Final Report v2 (NEW).docx".

To wrap up

Case styles are dialects: none is intrinsically best, each is native somewhere, and fluency means converting deliberately at the borders — identifiers to URLs, prose to headlines, data to code — with acronyms and existing names handled as the treaties they are.

When a team argues about case, it is rarely arguing about typography — it is arguing about whose home territory the code is. The settlement that ends the argument is a written style guide, one per layer, plus automated enforcement: a formatter or linter that applies the rule quietly is worth a hundred review comments, because it makes the convention ambient instead of personal. Record the acronym rulings in the same document — IDs or Ids, HTTP or Http, JSON or Json. Those few lines will be consulted more than any others in the guide, because they settle the cases the general rule cannot.

Try it yourself

The case converter switches text between UPPERCASE, lowercase, Title, Sentence, camelCase, PascalCase, snake_case, kebab-case, CONSTANT_CASE and alternating case — handy for checking exactly how a phrase survives each dialect.

Open the Case Converter