Text FIELD NOTES · 4 MIN READ
camelCase vs snake_case vs kebab-case: Why Programmers Can't Agree
Where each naming convention lives and why: what spaces, underscores, hyphens, and capital letters can legally do in code, CSS, and URLs.
Ask three programmers to name the same thing and you can get userLoginCount, user_login_count, and user-login-count — three spellings of one idea, each with its loyal following. The argument is older than it needs to be, but it is not arbitrary. Each style exists because somewhere in computing a certain character is forbidden, required, or dangerous. Learn the constraints and the camps suddenly make sense.
Five spellings, one name
Start with the zoo. Given the plain phrase "quarterly sales report", the conventions produce:
camelCase quarterlySalesReport (JavaScript, Java variables)
PascalCase QuarterlySalesReport (classes, types, components)
snake_case quarterly_sales_report (Python, SQL, filenames)
SCREAMING_SNAKE QUARTERLY_SALES_REPORT (constants, env variables)
kebab-case quarterly-sales-report (CSS, URLs, file names)
camelCase and PascalCase use capital letters to mark where words begin. snake_case and SCREAMING_SNAKE use underscores. kebab-case — also called dash-case or, in old Lisp circles, lisp-case — uses hyphens. All five say the same thing out loud; the difference is purely what characters the surrounding system allows.
Why the camps exist at all
Variable names can't contain spaces in essentially every programming language. That single rule creates the whole war. You need some way to show word boundaries in a space-free identifier, and there are only two characters up to the job. The underscore is legal in identifiers everywhere, which gives you snake_case — the natural choice in C culture, later codified by Python's PEP 8 style guide. Capital letters need no character at all, which gives you camelCase — a style that traveled from Smalltalk and Pascal into Java and then JavaScript, and became the default for variables and functions in those ecosystems.
Hyphens, meanwhile, are usually illegal in identifiers — the parser would read quarterly-sales as "quarterly minus sales". So kebab-case lives precisely where identifiers don't: CSS class names and custom properties, HTML attributes like data-user-count, command-line flags, file names, and URLs. Each convention is simply "what's legal where I live".
There is one more practical wrinkle: case sensitivity. camelCase breaks in places that fold case — web domains, some filesystems, human memory. userLoginCount and userlogincount are different names to a compiler and the same name to a tired person at 2 a.m. Lowercase styles (snake, kebab) are immune to that class of bug.
What a converter actually does
Here is what the real Case Converter produces for "Quarterly Sales Report FY2025":
camel: quarterlySalesReportFy2025
snake: quarterly_sales_report_fy2025
kebab: quarterly-sales-report-fy2025
title: Quarterly Sales Report Fy2025
sentence: Quarterly sales report fy2025
Look closely at Fy2025. The acronym FY came in as capitals, but the converter only knows boundaries where separators or spaces were — so in camelCase only the first letter of each chunk is capitalized, and the acronym gets flattened. That is not a bug; it is the honest limit of a converter that cannot know FY means "fiscal year". Acronyms are the classic place where machine conversion needs a human pass.
The converter is also good at cleaning up mess. Feed it user login count!! and snake_case gives user_login_count, kebab gives user-login-count: runs of spaces and punctuation collapse into a single separator, and leading or trailing separators get trimmed away.
Conversions are one-way streets
Try going the other way: convert quarterlySalesReportFy2025 to snake_case and you get quarterlysalesreportfy2025 — one long lowercase blob. The capitals that mark word boundaries for your eye are just ordinary letters to the converter, which looks for separator characters. Some converters do split on capital-letter "humps"; this one deliberately reads separators, which is why it never mangles input, but also why camel-to-snake needs the original phrase, not the camelCase version. Keep the human-readable original around; convert from it, never from a converted form.
Batch renaming, and picking a lane
Real projects rarely convert one name — they convert forty. The Case Convert Batch tool takes one name per line and converts the whole list to a single target case, which is exactly the job when you are normalizing a list of database columns, config keys, or labels before a rename. Paste, pick, copy the result.
As for which convention to choose: your ecosystem usually decides for you. JavaScript and Java lean camelCase, Python and SQL lean snake_case, CSS and URLs demand kebab-case, environment variables live in SCREAMING_SNAKE. Fighting the local convention costs more than it gains — code with one consistent style reads faster than code with the "best" one. And when the name has to be unique across systems rather than merely readable, that is a different problem entirely: identifiers like UUIDs exist to be collision-proof, not pretty (see How UUIDs Work).
Try it yourself
Throw a few of your own names at the Case Converter and watch how acronyms and messy spacing fare in each target case. Then run a real list — column names, keys, labels — through the Case Convert Batch tool and get them all into one convention in a single pass. And when the name's destination is a URL rather than a codebase, the Slug Generator produces the URL-flavored version of kebab-case, punctuation and accents included in the cleanup.