snake_case, camelCase, PascalCase, kebab-case: picking the right convention
getUserName, get_user_name, GetUserName, get-user-name — all express the same idea, but each ecosystem prefers a different shape. This article surveys the main naming conventions and where each fits.
Common conventions
| Name | Example | Aliases |
|---|---|---|
| camelCase | getUserName | lowerCamelCase |
| PascalCase | GetUserName | UpperCamelCase |
| snake_case | get_user_name | underscore_case |
| SCREAMING_SNAKE_CASE | GET_USER_NAME | constant_case |
| kebab-case | get-user-name | dash-case |
| flatcase | getusername | lowercase |
| dot.case | get.user.name | — |
| Train-Case | Get-User-Name | HTTP-Header-Case |
Conventions per language
| Language / domain | Variables / functions | Classes / types | Constants |
|---|---|---|---|
| JavaScript / TS | camelCase | PascalCase | UPPER_SNAKE |
| Python | snake_case | PascalCase | UPPER_SNAKE |
| Ruby | snake_case | PascalCase | UPPER_SNAKE |
| Java | camelCase | PascalCase | UPPER_SNAKE |
| C# | PascalCase (most things) | PascalCase | PascalCase |
| Go | camelCase / PascalCase | PascalCase | PascalCase |
| Rust | snake_case | PascalCase | UPPER_SNAKE |
| Swift | camelCase | PascalCase | camelCase |
| PHP | camelCase | PascalCase | UPPER_SNAKE |
C# uses PascalCase even for variables; Go uses capitalization to signal exported vs unexported (Foo exported, foo package-private).
Picking by destination
URLs (kebab-case)
/api/user-profiles/123
/products/red-running-shoes Reasons:
- Search engines treat hyphens as word separators.
- Underscores are sometimes treated as concatenation (worse for SEO).
- Uppercase introduces case-sensitivity issues.
Filenames (kebab-case or snake_case)
- React components: PascalCase (
UserProfile.tsx). - Generic files: kebab-case (
user-profile.ts) or snake_case (user_profile.py). - Match the community convention.
CSS classes (kebab-case)
.user-profile {
}
.btn-primary {
} BEM:
.block__element--modifier
.card__title--large HTML attributes (kebab-case)
<div data-user-id="123" data-is-active="true"></div> camelCase doesn’t work — attributes are case-folded. From JavaScript, you read them as dataset.userId (camelCase auto-mapping).
HTTP headers (Train-Case)
Content-Type: application/json
X-Forwarded-For: 192.168.1.1 Headers are case-insensitive per spec, but Train-Case is conventional.
JSON keys
No universal convention. Pick one per project:
- snake_case if the backend is Python / Ruby.
- camelCase if the frontend is JavaScript.
A common pattern is “match the consumer”. For a JS frontend, return camelCase from the API.
Constants (SCREAMING_SNAKE_CASE)
const MAX_RETRY_COUNT = 3;
const API_BASE_URL = 'https://...'; Universal. Visually distinguishes “values that don’t change”.
Conversion algorithm
// camelCase / PascalCase → words
function splitCamel(str) {
return str
.replace(/([a-z])([A-Z])/g, '$1 $2')
.toLowerCase()
.split(' ');
}
// snake_case / kebab-case → words
function splitDelimited(str) {
return str.split(/[-_]/);
}
// words → camelCase
function toCamel(words) {
return (
words[0].toLowerCase() +
words
.slice(1)
.map((w) => w[0].toUpperCase() + w.slice(1).toLowerCase())
.join('')
);
}
// words → snake_case / kebab-case
function toSnake(words) {
return words.map((w) => w.toLowerCase()).join('_');
}
function toKebab(words) {
return words.map((w) => w.toLowerCase()).join('-');
} Acronym runs (HTTPRequest, getURL) need care:
- Ideal:
HTTPRequest→["HTTP", "Request"] - Naive split:
HTTPRequest→["H", "T", "T", "P", "Request"]
A regex like [A-Z]+(?=[A-Z][a-z])|[A-Z][a-z]* handles the acronym case.
Cross-language API conversion
When servers and clients use different conventions, libraries help at the boundary:
- JavaScript:
camelcase-keys,snakecase-keys. - Rails: recent versions auto-camelize JSON output.
- Django REST Framework:
djangorestframework-camel-casemiddleware.
A Python (snake_case) server feeding a JS (camelCase) frontend typically converts at the API edge.
Summary
- Follow the language community’s convention by default.
- URLs and filenames lean kebab-case.
- Constants use SCREAMING_SNAKE_CASE everywhere.
- For API JSON, decide per project and stay consistent.
To convert between conventions quickly, the case converter on this site flips a string across all the common forms.