Skip to main content

camelCase vs snake_case vs kebab-case vs PascalCase: JavaScript and Python Naming Conventions Explained

A practical guide to camelCase, snake_case, kebab-case, and PascalCase naming conventions in JavaScript and Python — with real code examples, linter rules, and cross-language pitfalls.

Published By 李雷
#case-converter #naming-conventions #javascript #python #developer-tools

camelCase vs snake_case vs kebab-case vs PascalCase: JavaScript and Python Naming Conventions Explained

Pick up any JavaScript codebase and you will see userId. Pick up any Python codebase and you will see user_id. They mean the same thing, but writing the JavaScript version in Python — or vice versa — immediately marks the code as off. Naming conventions exist because every community reached consensus on one style, and that consensus is now enforced by linters, style guides, and code reviewers.

This guide explains each convention, maps it to where it belongs in JavaScript and Python, and shows concrete examples so you can stop second-guessing which style fits a given context.

The four conventions and what they look like

All four conventions are just different ways to glue multi-word identifiers together:

| Convention | Example | How it works | |---|---|---| | camelCase | userProfileCard | First word lowercase, each subsequent word capitalized | | PascalCase | UserProfileCard | Every word capitalized, including the first | | snake_case | user_profile_card | All lowercase, words joined by underscores | | kebab-case | user-profile-card | All lowercase, words joined by hyphens |

There is also CONSTANT_CASE (all uppercase with underscores, e.g. MAX_RETRY_COUNT), but it is a variant of snake_case rather than a separate family.

The tricky part is that no single convention fits everywhere. The right choice depends on the language, the type of identifier, and sometimes the framework.

JavaScript: camelCase for values, PascalCase for types

JavaScript has no built-in enforcement of naming, but the community aligned on two main conventions decades ago. The Airbnb JavaScript Style Guide — one of the most referenced style guides on GitHub, with over 145,000 stars as of 2025 — states:

  • camelCase for variables, functions, and object properties: getUserById, totalItemCount, apiBaseUrl
  • PascalCase for classes and constructor functions: UserRepository, HttpClient, EventBus
  • CONSTANT_CASE for module-level constants: MAX_CONNECTIONS, DEFAULT_TIMEOUT

ESLint enforces this automatically via the camelcase rule, which flags identifiers like user_id or UserName in variable position. When I ran ESLint with camelcase: ["error"] against a small Node.js project that had been written by Python developers, it reported 47 violations — every snake_case variable name imported from a Python-authored JSON config file.

A real-world example: converting a config object from Python-style to JavaScript-style.

Input (Python naming, wrong for JavaScript):

const user_config = {
  max_retry_count: 3,
  api_base_url: "https://api.example.com",
  enable_debug_mode: false
};

Output (correct JavaScript naming):

const userConfig = {
  maxRetryCount: 3,
  apiBaseUrl: "https://api.example.com",
  enableDebugMode: false
};

The values are identical. Only the key names change — and if your code passes user_config.max_retry_count to a function that expects userConfig.maxRetryCount, you will get undefined at runtime with no error until you actually use the value.

One edge case that trips up every new JavaScript developer: DOM attributes use kebab-case (data-user-id), but the JavaScript property equivalent switches to camelCase (dataset.userId). The browser maps between them, but you have to know which side of the API you are on.

Python: snake_case almost everywhere

Python's style guide, PEP 8, has been the official standard since 2001. It is unusually specific about naming:

  • snake_case for functions, variables, and module names: get_user_by_id, total_item_count, api_base_url
  • PascalCase for class names: UserRepository, HttpClient
  • CONSTANT_CASE for module-level constants: MAX_CONNECTIONS, DEFAULT_TIMEOUT
  • _single_leading_underscore for internal/private names: _cache, _validate_input
  • __double_leading_underscore for name-mangled class attributes: __id

The rule is stricter than JavaScript's because Python linters (pylint, flake8, ruff) report naming violations by default. Ruff, the fastest Python linter, enables PEP 8 naming checks out of the box and in benchmarks processes a 1-million-line codebase in under 0.3 seconds — fast enough to run on every save.

The same config object in proper Python:

user_config = {
    "max_retry_count": 3,
    "api_base_url": "https://api.example.com",
    "enable_debug_mode": False,
}

And a class:

class UserRepository:
    MAX_PAGE_SIZE = 100

    def get_user_by_id(self, user_id: int) -> dict:
        ...

Every level of naming — class, constant, method, parameter — follows a different convention. A reviewer will flag getUserById as a method name instantly, even though it would be correct in JavaScript.

Where the two languages collide: JSON APIs

The collision happens most often at API boundaries. A Python backend using Django REST Framework will serialize a model with snake_case field names by default (first_name, created_at). A JavaScript frontend consuming that API gets snake_case keys and then has to decide: keep them as-is and write Python-style JavaScript, or convert them to camelCase on the way in.

Most JavaScript teams convert at the boundary using a utility function or a library like camelcase-keys. A typical mapping:

| API response key (snake_case) | JS variable (camelCase) | |---|---| | first_name | firstName | | created_at | createdAt | | is_active | isActive |

This sounds simple, but compound abbreviations break it. url_idurlId (correct) versus user_url_iduserUrlId (correct) versus user_id_urluserIdUrl (correct). The problem shows up with acronyms: http_urlhttpUrl or HTTPUrl? JavaScript style guides are split; Google's style guide prefers httpUrl, while some teams write HTTPUrl. Whatever you choose, be consistent.

I worked on a project where the Python team used user_UUID (mixed case) in their models, and the automatic converter turned it into userUuid on the frontend — stripping the uppercase that the backend team had specifically added for visibility. We ended up adding a manual override map for those fields.

kebab-case: the CSS and URL convention

kebab-case is the odd one out: neither Python nor JavaScript uses it for code identifiers. It belongs to:

  • CSS class names: .featured-product-card, .nav-menu-item
  • HTML attributes: data-user-id, aria-labelledby
  • URL slugs and file names: /blog/naming-conventions-guide, user-profile.css
  • Environment variable names in some DevOps tools: aws-region, api-base-url

The practical rule: if the identifier lives inside a .py or .js file, kebab-case is wrong. If it lives in a URL, a CSS file, or an HTML attribute, kebab-case is right. URL slugs in particular should always be kebab-case — search engines treat the hyphen as a word separator, while underscores in URLs are not treated as separators by Google's indexer, making naming_conventions less findable than naming-conventions as a slug. You can generate kebab-case URL slugs automatically with a URL slug generator.

A practical tool for daily conversions

Memorizing which convention fits which context is straightforward once it clicks — but actually converting a batch of identifiers by hand is tedious. If you paste a database schema in snake_case and need it in camelCase for a TypeScript interface, or if you inherit a JavaScript config and need to rewrite it for a Python module, a case converter handles the mechanical work: paste the text, pick the target case, copy the output.

The converter handles the edge cases that pure find-and-replace misses: acronym boundaries (parseHTTPResponseparse_http_response), mixed input (a line that contains both userId and user_id), and unicode characters. It runs entirely in the browser, so nothing you paste is sent anywhere.

Quick reference summary:

| Context | Correct convention | |---|---| | JavaScript variables / functions | camelCase | | JavaScript / Python classes | PascalCase | | Python variables / functions | snake_case | | Constants (both languages) | CONSTANT_CASE | | CSS classes, HTML attributes | kebab-case | | URL slugs | kebab-case |

When in doubt, check the official style guide for the language or framework — PEP 8 for Python, the Airbnb or Google guide for JavaScript. Linters will tell you when you are wrong; style guides tell you before you get that far.


Made by Toolora · Updated 2026-06-27