convertCASEpro

MODE
Developers6 min read

snake_case vs kebab-case: A Developer's Guide

Both use lowercase letters and delimiters to separate words — but one uses underscores and the other hyphens. Here's exactly where each belongs and why you can't swap them.

Published May 1, 2025 · By Sudip Bhowmick

Two of the most commonly confused naming conventions in software development are snake_case and kebab-case. Both use all lowercase letters and separate words with a delimiter — but the delimiter is different, and that difference determines exactly where each format belongs. Getting them confused can break your CSS, produce invalid variable names, and create inconsistent URL structures.

What Is snake_case?

In snake_case, words are separated by underscores (_) and all letters are lowercase. The name comes from the visual appearance of the underscore-connected words lying flat on the line — like a snake. There is also an uppercase variant called CONSTANT_CASE (or SCREAMING_SNAKE_CASE) where all letters are uppercase.

  • user_name
  • first_name
  • get_user_by_id
  • database_connection_string
  • max_retry_count
  • MAX_RETRIES (CONSTANT_CASE variant)

What Is kebab-case?

In kebab-case, words are separated by hyphens (-) and all letters are lowercase. The name is a somewhat joking reference to words being 'skewered' together like meat on a kebab. It is also called spinal-case, lisp-case, or slug-case in different communities.

  • user-name
  • first-name
  • my-component
  • background-color
  • max-width
  • data-user-id

Where snake_case Is Used

Python: PEP 8 — the official Python style guide — mandates snake_case for variable names, function names, module names, and file names. Python code that uses camelCase or kebab-case is considered non-idiomatic and fails most linters.

Databases and SQL: Column names and table names in SQL databases conventionally use snake_case, especially in PostgreSQL. Fields like first_name, created_at, and order_total are standard across most database schemas.

Environment variables: While written in CONSTANT_CASE (DATABASE_URL, API_KEY, NODE_ENV), these follow the same underscore-as-separator rule. They are essentially uppercase snake_case.

Ruby and Rust: Both use snake_case for variable and function names, following a similar convention to Python.

File naming in Python projects: Python module files and package directories use snake_case — user_service.py, database_config.py.

Where kebab-case Is Used

CSS property names: All multi-word CSS properties use kebab-case — background-color, font-size, border-radius, margin-top, text-transform. This is not optional — CSS property names are defined this way in the specification.

HTML attributes: Custom data attributes and ARIA attributes use kebab-case — data-user-id, aria-label, data-track-event. Standard HTML attributes like accept-charset and http-equiv also use kebab-case.

URLs and URL slugs: Web URLs use kebab-case for both readability and SEO. Google's own documentation recommends hyphens over underscores in URLs because Google treats hyphens as word separators but treats underscores as part of the word. A URL like /blog/title-case-rules-explained ranks better than /blog/title_case_rules_explained.

npm package names: All npm packages are published with kebab-case names — react-router, lodash, express, vue-router, @tanstack/react-query. Package names cannot contain uppercase letters.

CLI flags: Command-line tools use kebab-case for flags and options — --dry-run, --output-file, --max-retries, --no-cache.

Why You Can't Swap Them

The critical reason snake_case and kebab-case are not interchangeable: hyphens (-) are parsed as the subtraction operator in most programming languages. Writing my-variable in Python, JavaScript, or Java is parsed as my minus variable — which either throws a SyntaxError or produces an unexpected result.

This is why kebab-case variable names do not exist in mainstream programming languages. Underscores, on the other hand, are valid identifier characters in virtually every language, which is why snake_case works safely as variable names.

The reverse is also true in CSS: CSS property names are kebab-case, and you cannot use underscores. background_color is not a valid CSS property — only background-color works.

Conclusion

The context makes the choice for you. Writing Python code or a SQL schema? Use snake_case. Writing CSS, HTML attributes, URL slugs, or npm package names? Use kebab-case. The hyphen that makes kebab-case readable in URLs is the same hyphen that makes it invalid as a variable name — so the two formats occupy different territories by necessity, not convention.

Free Tool

Try the snake_case Converter

Try It Free →