Editly

Published: 2026-05-13

camelCase vs snake_case: When to Use Which (With Examples)

camelCase or snake_case? The answer depends on your language, layer, and team convention. Full breakdown with language rules, API gotchas, and a conversion tool.

Side-by-side comparison of camelCase and snake_case variable naming conventions with language icons

The answer takes about 30 seconds to give and a career to fully internalize: use what the language community already decided. camelCase in JavaScript. snake_case in Python. Done.

But the real complexity is at the boundaries — JSON APIs, database schemas, config files, and cross-language projects where two communities collide. That's where things get messy, and that's what this article covers.


Quick Reference: Which Convention Goes Where

Before diving into the why, here's the definitive lookup table:

ContextConventionExample
JavaScript variables / functionscamelCasewordCount, parseText()
JavaScript classesPascalCaseTextAnalyzer, WordCounter
JavaScript constantsUPPER_SNAKE_CASEMAX_WORDS, DEFAULT_WPM
TypeScript interfaces / typesPascalCaseTextStats, AnalysisResult
TypeScript / Vue file nameskebab-caseword-counter.ts, text-analyzer.vue
Python variables / functionssnake_caseword_count, parse_text()
Python classesPascalCaseTextAnalyzer, WordCounter
Python constantsUPPER_SNAKE_CASEMAX_WORDS, DEFAULT_WPM
Ruby / Railssnake_caseword_count, parse_text
GocamelCase / PascalCasewordCount (unexported), WordCount (exported)
Java / Kotlin public methodscamelCasegetWordCount(), parseText()
SQL column namessnake_caseword_count, created_at
CSS class nameskebab-caseword-counter, text-toolbar
URL slugskebab-case/case-converter, /remove-spaces
npm package nameskebab-casenuxt-gtag, vue-router
JSON REST API keyscamelCase (JS-first) or snake_case (Python-first)wordCount / word_count
Environment variablesUPPER_SNAKE_CASENODE_ENV, API_SECRET

Bookmark that table. It covers 95% of the decisions you'll make on a given project.


camelCase: The JavaScript and Java Choice

camelCase concatenates words by capitalizing the first letter of each word after the first: wordCount, parseText, maxRetries.

Where it's the law:

  • JavaScript and TypeScript variables, functions, and object properties
  • Java instance methods and variables
  • Objective-C methods
  • JSON keys consumed by JavaScript frontends (by convention, not spec)
  • Go unexported identifiers (wordCount) and exported identifiers via PascalCase (WordCount)

The origin of camelCase in JavaScript traces directly to Java. Brendan Eich designed JavaScript's syntax to appeal to Java developers in 1995, and JavaScript's built-in APIs followed Java's convention: getElementById, addEventListener, hasOwnProperty. Fifteen years of browser APIs trained an entire generation to type camelCase instinctively.

The PascalCase variant (UpperCamelCase) capitalizes every word, including the first: TextAnalyzer, HttpRequest, WordCounter. In JavaScript, PascalCase signals "this is a constructor or class." In C# and Java, it's used for all public methods — a gotcha when you first read .NET source code coming from a JS background.


snake_case: The Python and Database Choice

snake_case lowercases everything and separates words with underscores: word_count, parse_text, max_retries.

Where it's the law:

  • Python variables, functions, and module names (PEP 8 — non-negotiable in any serious Python project)
  • Ruby and Rails methods and variables
  • PostgreSQL and MySQL column names (enforced by convention, not the DB engine)
  • Rust variables and functions
  • C standard library functions (printf, strlen — technically no separator, but single words)
  • Environment variable names in UPPER_SNAKE_CASE variant

Why Python chose snake_case: Guido van Rossum wrote PEP 8 in 2001 to describe the style already used in Python's standard library. The library predated PEP 8, and it used snake_case because Unix utilities and C had established that pattern for multi-word identifiers. Python simply codified existing practice.

The PostgreSQL trap with camelCase columns: SQL is case-insensitive by spec, and PostgreSQL folds every unquoted identifier to lowercase at parse time. If you create a column named wordCount, Postgres stores it as wordcount. Your SELECT wordCount FROM ... query silently works — until a junior dev writes SELECT "wordCount" FROM ... with quotes, gets a column "wordCount" does not exist error, and spends an hour debugging. The fix is to always quote it, which then means you must quote it everywhere forever. word_count has no such trap — it survives the case fold intact. Use snake_case and save yourself the bikeshedding. snake_case also aligns with how ORMs like SQLAlchemy, Prisma, and ActiveRecord generate migration column names by default.


The API Boundary Problem

This is where most teams make mistakes.

A Python backend (snake_case) serving a JavaScript frontend (camelCase) creates a decision: whose convention wins at the API layer?

Option 1: snake_case throughout The backend returns { "word_count": 432 }. The frontend accesses response.word_count. This works, but it feels wrong in JavaScript — properties that look like Python. If you're using TypeScript, your interfaces now have snake_case keys, which stands out against every JavaScript convention.

Option 2: camelCase throughout The backend serializes to { "wordCount": 432 }. FastAPI does this automatically with alias_generator. Django REST Framework supports it via a custom renderer. The frontend gets native-looking keys.

Option 3: pick a standard and stick to it JSON:API spec uses camelCase. OpenAPI recommendations favor camelCase. GraphQL (schema and queries) is strictly camelCase by convention. If you're building a public API, camelCase is what most SDK generators expect.

The worst option: mixing them. { "wordCount": 432, "created_at": "2026-05-13" } — this is what happens when two people wrote the serializer without talking. Normalize at the serializer layer, not the client.

Here's how the three options look in practice:

┌─────────────────────────────────────────────────────────────┐
│                    API BOUNDARY OPTIONS                     │
├───────────────┬─────────────────┬───────────────────────────┤
│ Option        │ API Response    │ Frontend access            │
├───────────────┼─────────────────┼───────────────────────────┤
│ snake_case    │ word_count: 432 │ response.word_count        │
│ camelCase     │ wordCount: 432  │ response.wordCount  ✓      │
│ Mixed (avoid) │ wordCount: 432, │ response.wordCount +       │
│               │ created_at: …   │ response.created_at  ✗    │
└───────────────┴─────────────────┴───────────────────────────┘

Converting Between Conventions

At some point you'll need to convert — either refactoring a codebase, adapting a third-party API response, or migrating a database schema.

The regex approach is the most reliable way to convert camelCase to snake_case programmatically:

// camelCase → snake_case
const toSnakeCase = (str) =>
  str.replace(/([a-z])([A-Z])/gu, '$1_$2').toLowerCase()

// snake_case → camelCase
const toCamelCase = (str) =>
  str.replace(/_([a-z])/gu, (_, c) => c.toUpperCase())

The key pattern is ([a-z])([A-Z]) — it matches every transition from lowercase to uppercase, which is exactly a camelCase boundary. Note the u flag: while this specific pattern only targets ASCII letters, building the u flag habit matters for any pattern that handles Unicode text.

VS Code step-by-step (no plugin needed):

  1. Open Find & Replace: Ctrl+H (Windows/Linux) or ⌘+H (Mac)
  2. Click the .* icon to enable regex mode
  3. Find: ([a-z])([A-Z])
  4. Replace: $1_$2
  5. Hit Replace All — this inserts underscores at every camelCase boundary
  6. Open the terminal and run the file through a lowercase pass, or do a second Find All → [A-Z] → lowercase manually

The $1 and $2 in the replacement string reference the two capture groups in the pattern — $1 is the lowercase letter before the boundary, $2 is the uppercase letter after it. A lot of devs don't realize VS Code's regex replace supports capture group back-references out of the box, no extension needed.

For one-off conversions, paste your identifier into our Case Converter — runs 100% in your browser, zero data sent to any server — and pick the output format from the dropdown.

For bulk renaming across a document or pasted code block, use Find & Replace with the regex ([a-z])([A-Z])$1_$2 to convert camelCase to snake_case, then follow up with a second pass to lowercase. The tool supports full regex with capture group substitution and shows a live match count before you commit.

If you're curious how the regex approach compares to other text processing patterns, the regex find & replace guide covers capture groups, quantifiers, and lookaheads in detail.


The Edge Cases That Trip Everyone Up

Acronyms in camelCase: Should it be parseHTML or parseHtml? getURL or getUrl? Google's Java style guide says treat acronyms as words: parseHtml, getUrl. Microsoft's C# guide says keep them uppercase if they're 2 characters: GetIO, but GetUrl. JavaScript has no universal rule. Pick one and document it — inconsistency within a codebase is the actual problem.

Numbers in identifiers: base64Encode or base_64_encode? The convention is to treat numbers as lowercase word characters: base64Encode, to_utf8. Some teams write toUtf8, some toUTF8 — again, the style guide matters more than the individual choice.

Leading underscores: _privateMethod is a JavaScript convention (not enforced by the language) to signal "don't call this from outside the module." Python uses a single leading underscore (_private) the same way, and double underscore (__mangled) triggers name mangling in classes. In modern JavaScript with #privateField syntax, the underscore convention is largely obsolete, but you'll still see it in older codebases.

Database primary keys: Most frameworks expect id, not Id or ID. Foreign keys follow the pattern user_id, post_id — snake_case with _id suffix. Keep this consistent or your ORM will generate queries that don't match your schema.


A Note on Tooling Enforcement

The most important property of a naming convention is that you don't have to think about it. If your team argues about case in code review, you're spending mental energy on the wrong thing.

ESLint has camelcase and @typescript-eslint/naming-convention rules that enforce casing at the linter level. Black (Python formatter) doesn't rename variables, but pylint and flake8 with PEP 8 plugins will flag snake_case violations. Set up the linter rule once, enforce on CI, and the conversation ends.

For ad-hoc text work — API responses, config files, migration scripts — the Case Converter handles all common formats including camelCase, snake_case, PascalCase, kebab-case, and UPPER_SNAKE_CASE in a single click.

And if you've ever pasted a blob of text with inconsistent casing and needed to normalize it, the approach in the how to remove extra spaces from text online article applies here too — clean the text first, then transform.


The Short Answer

  • JavaScript / TypeScript: camelCase for variables and functions, PascalCase for classes
  • Python: snake_case for variables and functions, PascalCase for classes, PEP 8 is not optional
  • SQL / Databases: snake_case, always
  • CSS / URLs / npm: kebab-case
  • Environment variables: UPPER_SNAKE_CASE
  • JSON APIs: camelCase if JS-first, snake_case if Python-first — pick one and serialize consistently

When you're working across layers and need to convert quickly, the Case Converter handles all formats without leaving the browser.

Frequently Asked Questions

Is camelCase or snake_case more readable?

Research is split, but context matters more than preference. Eye-tracking studies show snake_case is slightly faster to read for long identifiers because the underscores create clear visual separation — similar to spaces. camelCase is faster to type (no Shift key for underscore). Most readability differences disappear at identifier lengths under 15 characters. The real answer: match whatever the language community has already standardized.

Which naming convention does JavaScript use?

JavaScript uses camelCase for variables, function names, and object properties (const wordCount, function parseText). PascalCase (a.k.a. UpperCamelCase) is reserved for classes and constructors (class TextAnalyzer). Constants are often UPPER_SNAKE_CASE (const MAX_WORDS = 50000). JavaScript itself uses camelCase in all its built-in APIs: getElementById, addEventListener, querySelector.

Which naming convention does Python use?

PEP 8 — the Python style guide — specifies snake_case for variables, function names, and module names (word_count, parse_text, my_module). PascalCase for class names (TextAnalyzer). UPPER_SNAKE_CASE for constants (MAX_WORDS). Python's standard library follows PEP 8 almost universally, which creates strong community pressure to do the same.

What naming convention should I use for REST API JSON keys?

camelCase is more common for JSON APIs consumed by JavaScript clients — it eliminates the need for key transformation on the frontend. However, many Python-first APIs (Django REST Framework, FastAPI by default) return snake_case keys. The real problem arises when you mix them: a Python backend returning snake_case to a JavaScript frontend creates a translation layer. Pick one for the whole stack, or configure serialization consistently.

What is PascalCase and how is it different from camelCase?

PascalCase (also called UpperCamelCase) capitalizes the first letter of every word including the first: TextAnalyzer, WordCounter, HttpRequest. Regular camelCase (lowerCamelCase) starts lowercase: textAnalyzer, wordCounter, httpRequest. The distinction matters: JavaScript uses camelCase for functions/variables but PascalCase for classes. C# and Java use PascalCase for public methods — which surprises JS developers crossing over.

What about kebab-case? When is that used?

kebab-case uses hyphens: word-counter, text-analyzer, my-component. It's the standard for CSS class names, HTML attributes, URL slugs, and npm package names. You can't use kebab-case for JavaScript variable names (the hyphen is the minus operator), which is why CSS-in-JS and Vue's single-file components allow both — kebab-case in templates, camelCase in script. File naming in some projects also uses kebab-case (word-counter.ts).

How do I bulk-convert camelCase identifiers to snake_case?

The most reliable approach is regex find-and-replace. The pattern ([a-z])([A-Z]) matches every transition from a lowercase letter to an uppercase letter — a camelCase boundary. Replace with $1_$2 (or \1_\2 in some engines) then lowercase the result. In VS Code: Ctrl+H, enable regex, search ([a-z])([A-Z]), replace $1_$2. For bulk conversion across files, use the Find & Replace tool at /find-replace with the same pattern.

Try Our Free Word Counter

Instantly count words, check readability, and analyze your text.

Open Word Counter