Back to Blog
Dev

Naming Conventions in Software: camelCase, snake_case, PascalCase, and kebab-case Explained

Inconsistent naming is the most common source of cognitive friction in a codebase. Understanding when and why each convention exists turns naming from guesswork into a deliberate, team-wide communication tool.

Naming is not a stylistic preference — it is a communication tool. Every identifier in a codebase is a message from its author to every future reader, including future-you. The naming convention you choose determines how efficiently that message is conveyed, how easily code can be read across language boundaries, and how reliably automated tools can process your identifiers. This guide covers every major naming convention used in software development, explains why each exists, and provides clear guidance on when to use each one.

Programming naming conventions

Why Naming Conventions Matter

Naming conventions exist to solve a fundamental problem: natural-language identifiers contain multiple words, but most programming languages treat spaces as syntax delimiters. Without a convention, "get user profile" could become getUserProfile, get_user_profile, GetUserProfile, get-user-profile, or getuserprofile — all referring to the same concept but unrecognisable as related to each other by automated tools and cognitively jarring to human readers accustomed to a different convention.

Consistency within a codebase reduces the cognitive overhead of reading code. When every function name follows camelCase, readers don't need to parse each identifier individually — the visual pattern becomes automatic. When conventions are inconsistent, every identifier requires an extra moment of parsing, which accumulates into significant friction over a reading session. Studies of code comprehension consistently show that consistent formatting and naming significantly reduce error rates in code review and maintenance tasks.

Beyond human readability, naming conventions interact with tooling. Linters enforce conventions and catch violations. Code generation tools produce identifiers in specific conventions. Serialisation and deserialisation of API payloads often requires mapping between backend conventions (snake_case in Python, camelCase in Java) and API conventions (typically camelCase for JSON). Understanding the conventions and their tooling enables you to automate this mapping reliably rather than doing it manually.

camelCase

camelCase writes multi-word identifiers by starting with a lowercase letter and capitalising the first letter of each subsequent word: getUserProfile, calculateTotalPrice, isAuthenticated. The name comes from the capital letters resembling the humps of a camel. It is also called "lower camel case" to distinguish it from PascalCase.

camelCase is the dominant convention for variable names and function names in JavaScript, TypeScript, Java, C#, Swift, and many other languages. It is the standard for JSON object keys in most API design guidelines (the Google JSON Style Guide, the OpenAPI specification defaults). In CSS-in-JS libraries and JavaScript style objects, property names use camelCase (backgroundColor rather than background-color).

Acronyms within camelCase names are a common inconsistency point. Should it be getHTTPRequest or getHttpRequest? parseURL or parseUrl? Both approaches are used in major codebases. The more maintainable convention is to treat acronyms as regular words: getHttpRequest, parseUrl, xmlParser. This is consistent with how the name reads aloud and avoids visual breaking of the camelCase rhythm for longer acronyms. Establish a team decision and encode it in your linter configuration.

PascalCase

PascalCase (also called UpperCamelCase) capitalises the first letter of every word, including the first: UserProfile, HttpRequest, CalculateTotalPrice. It is named after the Pascal programming language, which popularised this convention for type names.

PascalCase is the standard for type names, class names, interface names, and component names across virtually all modern languages and frameworks. In JavaScript and TypeScript: classes, interfaces, type aliases, enums, and React components use PascalCase. In C#: all public identifiers use PascalCase. In Go: exported identifiers (public) use PascalCase, unexported identifiers use camelCase.

The visual distinction between PascalCase and camelCase is deliberate. A leading capital letter signals "this is a type, constructor, or class" rather than "this is a value or function." This convention is so deeply embedded in most ecosystems that code that violates it — a class named in camelCase, or a value named in PascalCase — immediately reads as wrong to experienced developers, even before they identify the specific problem.

snake_case

snake_case separates words with underscores, all in lowercase: user_profile, calculate_total_price, is_authenticated. The name describes the flat, horizontal appearance of the underscores linking words together.

snake_case is the dominant convention in Python (PEP 8 requires snake_case for variable names, function names, and module names), Ruby, Rust (which uses snake_case for variables and functions), and C (for functions and variables). It is also the standard convention for SQL column names and database table names, which is why Python ORMs and Django models use snake_case for field names that map directly to database columns.

snake_case is arguably easier to read than camelCase for long identifiers, because the underscore provides clearer visual separation than a capital letter. Research on identifier readability generally supports this — readers are slightly faster at segmenting snake_case identifiers into their component words. However, it is more verbose and less compact than camelCase, which matters in contexts like minified JavaScript where identifier length affects file size.

SCREAMING_SNAKE_CASE

SCREAMING_SNAKE_CASE (also called UPPER_SNAKE_CASE or MACRO_CASE) is snake_case with all letters capitalised: MAX_RETRY_COUNT, DATABASE_URL, DEFAULT_TIMEOUT_MS. The name refers to the visual intensity of all-caps text.

This convention is universally used for constants — values that do not change after initialisation — across virtually all languages: Python (CONSTANT_VALUE = 42), JavaScript/TypeScript (const MAX_SIZE = 100), C (#define MAX_SIZE 100), Java (static final int MAX_SIZE = 100), Rust (constant and static items). Environment variable names conventionally use SCREAMING_SNAKE_CASE: DATABASE_URL, SECRET_KEY, NODE_ENV.

The convention serves as a visual flag: any reader seeing an all-caps identifier immediately knows they are looking at a constant value, not a computed value or mutable variable. This is valuable during code review and debugging — constants don't need to be traced through execution flow, which simplifies reasoning about code behaviour.

kebab-case

kebab-case separates words with hyphens, all in lowercase: user-profile, calculate-total-price, is-authenticated. The name describes the skewered appearance of words linked by hyphens, like items on a kebab skewer.

kebab-case is the standard convention for CSS class names, HTML element IDs, CSS custom properties (--font-size-large), HTML attribute names, and URL paths. It is also used for npm package names (react-router, express-validator), CLI flag names (--output-file, --dry-run), and YAML/TOML configuration keys in some ecosystems.

kebab-case cannot be used as an identifier in most programming languages because the hyphen is the subtraction operator — user-profile in JavaScript is parsed as user minus profile. This is why HTML attributes and CSS use kebab-case (they have their own parsers that don't treat hyphens as operators) while JavaScript uses camelCase (the language uses hyphens as operators). The mapping between CSS property names and JavaScript style object keys — background-colorbackgroundColor — is a direct consequence of this language constraint.

Code style linting and naming

Language-Specific Conventions at a Glance

JavaScript/TypeScript: camelCase for variables and functions; PascalCase for classes, interfaces, types, React components, and enums; SCREAMING_SNAKE_CASE for module-level constants; kebab-case for CSS classes and file names (in many style guides). Python: snake_case for variables, functions, methods, and modules; PascalCase for classes; SCREAMING_SNAKE_CASE for constants. Go: camelCase for unexported identifiers; PascalCase for exported identifiers; no underscores in typical Go style. Rust: snake_case for variables, functions, modules, and file names; PascalCase for types, structs, enums, traits; SCREAMING_SNAKE_CASE for constants and statics. CSS: kebab-case for class names, IDs, custom properties, and file names.

Database conventions diverge from language conventions in important ways. SQL keywords are traditionally uppercase (SELECT, FROM, WHERE), though most databases are case-insensitive for keywords. Column names and table names use snake_case by convention in PostgreSQL, MySQL, and SQLite. This creates a naming boundary when ORM-based code maps Python snake_case model fields to camelCase JSON output — a mapping that frameworks like Django REST Framework and SQLAlchemy handle automatically but that you need to understand to debug correctly.

Automated Convention Enforcement

Manual enforcement of naming conventions through code review is slow and inconsistent. Linters encode conventions as machine-checkable rules that run in milliseconds. ESLint's camelcase rule, the naming-convention rule in TypeScript ESLint, Pylint's naming checks, and Clippy's Rust naming lints all provide automated enforcement at development time and in CI/CD pipelines. Configure these rules in your project's linter configuration file and include them in your pre-commit hooks to prevent convention violations from reaching your main branch.

Our free Case Converter tool handles the mechanical work of converting identifiers between conventions — paste a name in any format and get the equivalent in camelCase, PascalCase, snake_case, SCREAMING_SNAKE_CASE, kebab-case, and more simultaneously. This is useful when working across language boundaries, when refactoring inconsistent legacy code, during API response mapping, or any time you need a reliable conversion without mental effort.

More Articles