Snake Case vs Kebab Case: Which Should You Use in Programming?
Snake case and kebab case are two of the most common identifier styles in modern software. They look almost identical — the only visible difference is the separator character — but that single character changes where each style can be used. In some languages snake_case is required; in others, kebab-case is impossible. This guide compares the two head-to-head so you can pick the right one for your codebase.
What Is Snake Case?
Snake case writes multi-word identifiers in lowercase with underscores between words: user_profile, get_total_amount, max_retry_count. The name comes from the way underscores resemble a snake slithering between the words. Snake case has been around since the earliest days of C and is deeply embedded in the Unix and scientific computing ecosystems.
It is the conventional style for variables, functions, and module names in Python (PEP 8), Ruby, Rust, and most database systems. Constants typically use an uppercase variant called SCREAMING_SNAKE_CASE or CONSTANT_CASE.
What Is Kebab Case?
Kebab case writes identifiers in lowercase with hyphens between words: user-profile, get-total-amount, max-retry-count. The name comes from the way the words look skewered on a hyphen, like meat on a kebab. Kebab case is also called "dash-case," "lisp-case," or "spinal-case."
It is the standard for URL slugs, CSS class names, HTML attribute values, package names in npm, command-line flags, and most configuration file keys. Lisp dialects (Clojure, Scheme) use kebab-case for variables and functions because the hyphen is a legal identifier character in those languages.
Same concept, three styles:
snake_case: customer_account_id
kebab-case: customer-account-id
camelCase: customerAccountId
The Critical Difference: Where You Can Use Each
The single most important fact about kebab case is that the hyphen is a subtraction operator in almost every mainstream programming language. That means user-profile is parsed as "the variable user minus the variable profile," not as a single identifier. As a result, kebab case is illegal as a variable or function name in JavaScript, Python, Java, C, C++, C#, Go, Rust, Ruby, and PHP.
Snake case has no such conflict. The underscore is a regular identifier character in every major language, so snake_case works everywhere a name is required.
| Context | snake_case OK? | kebab-case OK? |
|---|---|---|
| Python variables | Yes (PEP 8) | No (syntax error) |
| JavaScript variables | Yes | No (parsed as subtraction) |
| CSS class names | Yes | Yes (preferred) |
| HTML attributes | No (non-standard) | Yes (data-user-id) |
| URL paths | Allowed | Preferred (SEO) |
| npm package names | No (invalid) | Yes |
| Database column names | Standard | Requires quoting |
| Environment variables | SCREAMING_SNAKE | No |
| JSON keys | Common | Allowed but rare |
When to Use snake_case
Use snake_case when the identifier must be referenced from program code. That includes Python and Ruby variables and methods, Rust functions and modules, database table and column names, JSON API keys consumed by Python or Ruby backends, environment variables (uppercase), and most file names in scientific Python codebases. If you are starting a new Python project, snake_case is non-negotiable for functions and variables — linters will flag anything else.
You can quickly normalize messy input into snake_case with our snake case converter. It strips punctuation, lowercases letters, and joins words with underscores.
When to Use kebab-case
Use kebab-case when the identifier appears in a context that does not parse it as code. The big four are URLs, CSS, HTML attributes, and file names on disk. Search engines treat hyphens as word separators in URLs, so /snake-case-vs-kebab-case ranks better than /snake_case_vs_kebab_case. CSS frameworks like BEM and Tailwind use kebab-case throughout. npm requires lowercase kebab-case for package names, and most CLIs use kebab-case for long flags (--dry-run, --max-old-space-size).
Mixing the Two in One Project
Most real codebases use both. A typical web application might use camelCase for JavaScript variables, kebab-case for CSS classes and URL slugs, and snake_case for the Python or Ruby backend and the SQL database. The trick is to be consistent within each layer and to apply translation cleanly at the boundaries. For example, a backend that returns user_id in JSON might be normalized to userId in the JavaScript client. Learn more in our JSON key naming guide.
Frequently Asked Questions
Is kebab-case faster to read than snake_case?
Studies on identifier readability generally find no meaningful difference between the two. Both clearly separate words and are easier to scan than camelCase for long names. Choose based on language requirements, not aesthetics.
Why can't I use kebab-case in JavaScript variable names?
Because the hyphen is the minus operator. let user-id = 5 is parsed as "assign 5 to the expression user-id," which is invalid syntax. Use camelCase or snake_case instead.
Which is better for SEO, snake_case or kebab-case URLs?
Kebab-case. Google explicitly treats hyphens as word separators in URLs but treats underscores as part of a single token. So /blue-widgets matches a search for "blue widgets" better than /blue_widgets does.