The short version
- Match the surrounding ecosystem. Consistency beats any argument about which convention is better.
- URLs should use kebab-case — Google treats hyphens as word separators and underscores as joiners.
- CSS, HTML attributes and command-line flags are kebab-case almost universally.
- Environment variables are CONSTANT_CASE by long convention, and some shells only reliably handle that form.
- Converting case is lossy at acronyms: HTTPServer, HttpServer and httpServer do not round-trip cleanly.
Naming conventions are pure convention — there is no technical reason Python uses snake_case and JavaScript uses camelCase. What matters is that code which follows its ecosystem's convention is readable by everyone in it, and code that does not is a small tax on every future reader. So the useful knowledge is not which case is best but which case each context expects.
There are really only a handful of shapes, distinguished by how word boundaries are marked: a capital letter, an underscore, a hyphen, or nothing at all. The names for them are informal but widely understood, and the table below fixes the vocabulary.
One of these choices does have a consequence beyond taste. In URLs, Google has long treated a hyphen as a word separator and an underscore as a word joiner, which means `blue-widgets` reads as two words and `blue_widgets` reads as one. That makes kebab-case the correct choice for any URL slug, and it is the only item in this guide where the decision is not simply stylistic.
The conventions, named
These are the forms in common use, with the names most developers will recognise. The last few are novelty transformations rather than conventions anyone codes in, but they turn up in tooling and in text manipulation.
| Name | Example | Typically used for |
|---|---|---|
| camelCase | userAccountId | JS/TS variables and functions, Java methods |
| PascalCase | UserAccountId | Classes, types, React components, Go exports |
| snake_case | user_account_id | Python, Ruby, Rust functions, SQL columns |
| CONSTANT_CASE | USER_ACCOUNT_ID | Constants and environment variables |
| kebab-case | user-account-id | URLs, CSS classes, HTML attributes, CLI flags |
| Train-Case | User-Account-Id | HTTP header names |
| dot.case | user.account.id | Config keys, namespaced properties |
| path/case | user/account/id | Filesystem and route paths |
| Title Case | User Account Id | Headings and human-facing labels |
| Sentence case | User account id | UI copy, labels, button text |
What each language actually expects
Most languages have a documented style guide, and following it is the whole game. Where a language has an official one — Python's PEP 8, Rust's naming guidelines, Go's own conventions enforced by its tooling — that document wins over any personal preference, because everyone else in that ecosystem is following it.
Note how often one language uses several conventions at once, differentiated by what is being named. JavaScript uses camelCase for variables, PascalCase for classes and components, and CONSTANT_CASE for module-level constants. That is not inconsistency; the convention carries information about the kind of thing you are looking at.
Go is the interesting case because its convention is load-bearing rather than cosmetic: an identifier starting with a capital letter is exported from its package and one starting lowercase is not. There, changing the case changes the program.
| Context | Variables / functions | Types / classes | Constants |
|---|---|---|---|
| JavaScript / TypeScript | camelCase | PascalCase | CONSTANT_CASE |
| Python (PEP 8) | snake_case | PascalCase | CONSTANT_CASE |
| Ruby | snake_case | PascalCase | CONSTANT_CASE |
| Rust | snake_case | PascalCase | CONSTANT_CASE |
| Go | camelCase (unexported) | PascalCase (exported) | PascalCase or camelCase |
| Java / C# | camelCase (Java), PascalCase (C# methods) | PascalCase | CONSTANT_CASE |
| PHP | camelCase | PascalCase | CONSTANT_CASE |
| SQL | snake_case | snake_case | CONSTANT_CASE |
| CSS | kebab-case | n/a | kebab-case (custom properties) |
URLs: the one choice with a real consequence
Google's guidance on URL structure is explicit that hyphens are the separator to use and underscores are not recommended. The mechanism is straightforward: a hyphen is treated as a word break, so `/image-compressor` is understood as two words that can each match a query, while `/image_compressor` tends to be read as one token that matches neither well.
So URL slugs are kebab-case, lowercase, and made of real words. That is why every route on this site looks the way it does — `background-remover` rather than `bgremove`, which is also why the tool registry keeps a terse internal identifier separate from the descriptive slug a visitor and a crawler see.
Two related points. Keep slugs lowercase, because paths are case-sensitive on most servers and a mixed-case URL invites duplicate-content problems when something links to a different capitalisation. And avoid changing a live slug at all — if you must, it needs a redirect, or you discard whatever ranking the old URL had accumulated.
- Use hyphens, not underscores, in URL slugs.
- Keep slugs lowercase — paths are case-sensitive on most servers.
- Prefer real words to abbreviations; the slug is what a searcher reads.
- Changing a live slug needs a redirect or the old URL's ranking is lost.
Filenames, environment variables and headers
Outside source code, three contexts have conventions worth knowing because breaking them causes real bugs rather than stylistic complaints.
Filenames are safest in kebab-case or snake_case, lowercase. The reason is that macOS and Windows filesystems are case-insensitive by default while Linux is case-sensitive, so a project that refers to `MyComponent.tsx` as `mycomponent.tsx` somewhere works on a developer's laptop and fails in a Linux build. Spaces are worth avoiding for the same class of reason — they need quoting in every shell command that touches them.
Environment variables are CONSTANT_CASE by universal convention. This is close to a hard requirement: shells treat variable names with hyphens as invalid, and lowercase names risk colliding with shell-internal variables. Anything reading configuration from the environment should expect uppercase with underscores.
HTTP header names are conventionally Train-Case, as in `Content-Type`. In practice they are case-insensitive per the specification, and HTTP/2 requires them lowercase on the wire, so the convention is for human readability rather than correctness.
Why converting case is not fully reversible
Automated case conversion works by finding word boundaries and re-marking them, and that first step is genuinely ambiguous in two situations. Knowing them prevents a surprising class of bug when converting a whole codebase or a set of database columns.
Acronyms are the main one. Converting `HTTPServer` to snake_case could reasonably give `http_server` or `h_t_t_p_server`, depending on whether consecutive capitals are treated as one word or many. Converting back gives `HttpServer`, not the original. This is why style guides for languages like Go and Swift take an explicit position on acronym casing, and why a round trip through two conversions should never be assumed safe.
Digits are the other. In `user2Id` or `oauth2Token`, whether a boundary exists before or after the digit is a judgement call, and different tools make it differently. Where identifiers mix letters and digits, check the output rather than trusting it.
The practical rule is to convert in one direction, review the result, and commit that — never convert back and forth expecting to arrive where you started.
Try it on Snake Case Converter
Free, no signup, no watermark. Runs on Zyff’s servers, so you get the same result on a phone as on a desktop.
At a glance
| Conversions available | 17 styles, including all the conventions above |
|---|---|
| Programming cases | camelCase, PascalCase, snake_case, CONSTANT_CASE, kebab-case, dot.case, path/case |
| Text cases | UPPERCASE, lowercase, Sentence case, Title Case, Capitalized Case |
| URL slugs | kebab-case, lowercase |
| Environment variables | CONSTANT_CASE |
| Price | Free, no account needed |
Frequently asked questions
What is the difference between camelCase and PascalCase?
Both join words by capitalising each one, but camelCase starts lowercase (userAccountId) and PascalCase starts uppercase (UserAccountId). The usual division is camelCase for variables and functions and PascalCase for classes, types and components — so the case itself tells a reader what kind of thing they are looking at.
Should URLs use hyphens or underscores?
Hyphens. Google's own URL guidance recommends hyphens and advises against underscores, because a hyphen is treated as a word separator while an underscore tends to join words into a single token. So /image-compressor is read as two matchable words and /image_compressor is not.
What is snake_case used for?
It is the standard for variables and functions in Python, Ruby and Rust, and for table and column names in SQL. Python's PEP 8 specifies it explicitly. It is also a safe choice for filenames, since it avoids both spaces and the case-sensitivity differences between Linux and macOS or Windows filesystems.
Which naming convention should I use for CSS classes?
kebab-case, which is what CSS itself uses for properties and custom properties and is near-universal for class names. If you need more structure than that, BEM layers a convention on top of kebab-case using double underscores and double hyphens for elements and modifiers, rather than replacing it.
Do environment variables have to be uppercase?
In practice, effectively yes. CONSTANT_CASE is the universal convention, hyphens are invalid in shell variable names, and lowercase names risk colliding with shell-internal variables. Anything reading configuration from the environment should expect uppercase words separated by underscores.
Why did converting my code's case break the acronyms?
Because word-boundary detection is genuinely ambiguous around consecutive capitals. HTTPServer can reasonably become http_server or h_t_t_p_server, and converting back yields HttpServer rather than the original. Convert in one direction, review the output, and never assume a round trip returns what you started with.
Does it matter which naming convention I pick?
Only that you match the ecosystem you are working in — every convention here is arbitrary, and consistency is the entire benefit. The one genuine exception is URLs, where hyphens versus underscores has a documented effect on how search engines read the slug.