Alex Garbiak
← Lib

Case Conventions in Python, JavaScript and SQL Server

The cases themselves are just word-separator rules — how a multi-word name like user account id gets squashed into a single valid identifier. The convention a language uses on top of that is a separate, mostly arbitrary choice, which is why the same concept (a variable, a class, a constant) can look completely different depending on which of the three you’re writing.

The cases

CaseExampleSeparator
snake_caseuser_account_idunderscore, all lowercase
SCREAMING_SNAKE_CASEMAX_RETRY_COUNTunderscore, all uppercase
camelCaseuserAccountIdnone — capitalize each word after the first
PascalCaseUserAccountIdnone — capitalize every word, including the first
kebab-caseuser-account-idhyphen, all lowercase

kebab-case is unusual in that almost no programming language accepts a hyphen inside an identifier — user-account-id as a variable name parses as user MINUS account MINUS id. It survives mainly in places that were never identifiers to begin with: URLs, filenames, CSS class names, npm package names, CLI flags (--dry-run).

Python

Python’s own style guide, PEP 8, is unusually explicit about this and most Python code follows it closely:

WhatConventionExample
Variables, functionssnake_casedef get_user_by_id():
Modules, packagessnake_caseimport json_schema_to_zod
Classes, exceptionsPascalCaseclass UserAccount:
ConstantsSCREAMING_SNAKE_CASEMAX_RETRY_COUNT = 5
“Private” attributesleading underscoreself._cache, def _helper():
Name-mangled attributesleading double underscoreself.__internal_state

The single case that trips people up coming from JavaScript is that Python functions and variables are snake_case, not camelCase — getUserById is valid Python but reads as foreign the moment anyone familiar with PEP 8 sees it.

JavaScript / TypeScript

JavaScript has no single official style guide — Airbnb’s and Google’s are the two most widely adopted — but the conventions below are close to universal regardless of which one a project follows:

WhatConventionExample
Variables, functionscamelCasefunction getUserById() {}
Classes, React/Vue components, TS types & interfacesPascalCaseclass UserAccount {}, <UserCard />, type UserAccount = {...}
Constants (module-level, truly immutable)SCREAMING_SNAKE_CASEconst MAX_RETRY_COUNT = 5;
“Private” class fieldsleading underscore (convention) or # (real private, ES2022+)this._cache, #internalState
Filenamesmixed — kebab-case or camelCase for modules, PascalCase for component filessql-format.ts, SqlFormatter.astro

The SCREAMING_SNAKE_CASE constant convention is weaker in JavaScript than in Python — it’s generally reserved for true global constants (MAX_RETRIES, enum-like objects) rather than every const declaration, since const in JS just means “not reassigned,” not “immutable value.”

SQL Server

SQL Server identifiers are case-insensitive by default (the server’s default collation is almost always case-insensitive, so UserAccount and useraccount refer to the same object) which is exactly why a written convention matters more here, not less — nothing in the engine enforces it, so drift is silent. Two conventions dominate in practice, and which one a codebase uses is usually just inherited from whichever ORM or team wrote the original schema:

WhatConventionExample
Tables, views, columns (T-SQL / Microsoft house style)PascalCaseCREATE TABLE UserAccount (AccountId INT, CreatedDate DATETIME2)
Tables, views, columns (portable/Postgres-influenced style)snake_caseCREATE TABLE user_account (account_id INT, created_date DATETIME2)
Stored proceduresPascalCase, often prefixedusp_GetUserById, spGetUserById
Variables (T-SQL script)camelCase or PascalCase, always @-prefixedDECLARE @userId INT;
Temp tables# prefix, otherwise same as tables#TempUserAccount

Two things worth knowing before writing a WHERE clause against an unfamiliar schema: because identifiers are case-insensitive, a query written against UserAccount still matches a table physically named useraccount; but string data inside columns is compared using the column’s collation, which is usually case-insensitive too (CI in the collation name) but isn’t guaranteed — a CS (case-sensitive) collation means WHERE Email = '[email protected]' won’t match a stored '[email protected]'. See SQL Server: Schema Discovery Without Admin Access for how to check a column’s actual datatype and collation before relying on either assumption.

Cross-language quick reference

The same logical name, as it would actually appear in each context:

ConceptPythonJavaScriptSQL Server (PascalCase house style)
a variableuser_iduserId@userId (T-SQL variable)
a function/procedureget_user_by_idgetUserByIdusp_GetUserById
a class/tableUserAccountUserAccountUserAccount
a constantMAX_RETRIESMAX_RETRIESn/a — no constant concept in T-SQL