Snake Case Converter: snake_case, SCREAMING_SNAKE and kebab-case

UPPERLOWERCASE.COM Snake Case Converter snake_case, SCREAMING_SNAKE, kebab-case before user first name after user_first_name

snake_case joins words with underscores and keeps every letter lowercase: user_first_name, max_retry_count, created_at. Put the same words in capitals and you get SCREAMING_SNAKE_CASE, the convention for constants. Swap the underscore for a hyphen and you get kebab-case, the convention for URLs and CSS.

The converter below produces all four, and turns an existing identifier back into readable words. Below it: which language expects which style, why PostgreSQL quietly lowercases your column names, and why Google asks for hyphens rather than underscores in a URL.

RESULT

Need the other styles too? The full upper lower case converter covers UPPERCASE, lowercase, Sentence case, Title Case, camelCase and more, with a live character count. Free, no sign-up.

snake_case and its relatives

Four separator styles, one underlying idea: replace the space with a character that identifiers are allowed to contain.

StyleSame three wordsAlso calledTypical home
snake_caseuser_first_nameunderscore case, pothole casePython, Ruby, SQL, Rust
SCREAMING_SNAKE_CASEUSER_FIRST_NAMEconstant case, macro caseConstants, environment variables
kebab-caseuser-first-namedash case, spinal caseURLs, CSS, HTML attributes
dot.caseuser.first.nameproperty caseConfig files, message keys
camelCaseuserFirstNamelower camel caseJavaScript, Java, Swift
PascalCaseUserFirstNameupper camel caseClass names everywhere

The names are informal and inconsistent, which is why a tool that offers constant case and one that offers SCREAMING_SNAKE_CASE mean the same thing. The two camel styles have their own guide: camelCase and PascalCase explained.

Where snake_case is the standard

These are not preferences. Each is written down in the language’s official style guide and enforced by its linter.

ContextConventionSet by
Python variables and functionssnake_casePEP 8
Python constantsSCREAMING_SNAKE_CASEPEP 8
Ruby variables and methodssnake_caseRuby style guide
Rust variables and functionssnake_caseRust API guidelines
C and C++ (traditional)snake_caseLong-standing practice
SQL tables and columnssnake_casePortability across engines
Environment variablesSCREAMING_SNAKE_CASEPOSIX convention
YAML and TOML keyssnake_case or kebab-caseProject choice
URLs and slugskebab-caseGoogle search guidelines
CSS classes and custom propertieskebab-caseCSS convention

Underscores and hyphens are not interchangeable in a URL. Google has said for years that it treats a hyphen as a word separator and an underscore as a joiner, so /red_shoes can be read as the single token redshoes while /red-shoes is read as two words. Use kebab-case in every public URL and keep underscores for code.

Why databases fold your column names

There is a concrete technical reason SQL settled on snake_case, and it catches people who arrive from a camelCase language.

In the SQL standard, an unquoted identifier is case insensitive. PostgreSQL implements that by folding unquoted identifiers to lowercase, so a column created as firstName is stored as firstname. Query it as firstName and it still works, because that folds too. Query it as "firstName", in double quotes, and it fails: the quoted form is case sensitive and there is no column by that exact name.

EngineUnquoted identifierConsequence
PostgreSQLFolded to lowercasefirstName becomes firstname
OracleFolded to UPPERCASEfirstName becomes FIRSTNAME
MySQL on LinuxTable names case sensitiveUsers and users are two tables
MySQL on WindowsTable names case insensitiveThe same schema behaves differently
SQL ServerDepends on collationUsually case insensitive

snake_case sidesteps all of it. A name that contains no capital letters cannot be folded into something different, so it behaves identically on every engine and on every operating system. That is the whole argument, and it is why an ORM that generates created_at rather than createdAt is doing you a favour.

How to convert to snake_case in code

LanguageApproach
Python'_'.join(text.lower().split()) for words; a small loop for camelCase input
JavaScriptInsert an underscore before each capital, then lowercase the whole string
Lodash_.snakeCase('userFirstName') returns user_first_name
RubyRails adds 'UserFirstName'.underscore
SQLLOWER(REPLACE(name, ' ', '_'))
Excel=LOWER(SUBSTITUTE(TRIM(A1)," ","_"))
Shelltr 'A-Z ' 'a-z_'

The Excel formula is worth keeping: TRIM removes the double spaces that would otherwise become double underscores, SUBSTITUTE swaps space for underscore, and LOWER flattens the case. The other spreadsheet case recipes are collected in upper and lower case in Excel and converting text to uppercase in Excel.

Converting from camelCase is the harder direction, because the boundary is a capital letter rather than a space, and consecutive capitals such as HTTPResponse have no obvious split point. The converter above handles both: it detects a lowercase-to-uppercase transition and an acronym followed by a normal word.

SCREAMING_SNAKE_CASE: constants and environment variables

Capitals in code carry one meaning almost universally: this value does not change. MAX_RETRIES, DEFAULT_TIMEOUT, API_BASE_URL. The convention predates most modern languages and comes from C, where macros were written in capitals so a reader could see that the compiler would substitute text rather than evaluate a variable.

Environment variables follow the same rule for a different reason. The POSIX specification reserves lowercase names for the shell’s own use, so an exported variable in capitals cannot collide with one of the shell’s internals. DATABASE_URL is not shouting, it is staying out of the way.

NameReads asCorrect?
MAX_RETRIESA constantYes
maxRetriesA variableOnly if it can change
DATABASE_URLAn environment variableYes
database_urlA local variableWrong for an env var
Max_RetriesNothing standardNo convention uses this

The last row is the trap. Mixed capitals with underscores belongs to no published style guide, exactly as Capitalize Each Word belongs to no prose style guide — a point made in detail in should all letters in a title be capitalized. A run of capitals is also slower for a human to read, which is why the convention is reserved for short names; the reasoning is set out in uppercase vs lowercase.

kebab-case: URLs, CSS and file names

The hyphen is the separator you use when the underscore is unavailable or unhelpful.

  • URLs. Hyphens are read as word boundaries by search engines; underscores are not. /upper-lower-case-converter is three words to Google, /upper_lower_case_converter is closer to one.
  • CSS. Class names, custom properties and every property in the language itself use hyphens: background-color, --brand-yellow, .site-header.
  • HTML attributes. data-user-id in the markup, read back as dataset.userId in JavaScript. The browser does the conversion because attribute names are case insensitive and identifiers are not.
  • Public file names. A hyphen survives being pasted into an email or a chat window; an underscore is often swallowed by the underline of an automatic link.

Hyphens are illegal in identifiers. In every C-family language a hyphen is the minus operator, so user-name parses as user minus name. That is the entire reason snake_case exists: the underscore is the only separator that a compiler will accept inside a name.

snake_case or camelCase: does it matter?

For readability, marginally. Studies of code comprehension have generally found snake_case slightly faster to read for people unfamiliar with the code, with the advantage shrinking to almost nothing among developers used to the style in front of them. The underscore is an explicit boundary; a capital letter is an implicit one.

For everything else, the choice is made for you. Python code written in camelCase will fail review, JavaScript written in snake_case will fail review, and both linters will say so before a human does. The only real decision left is at the boundaries between systems, and there the rule is to convert once, in one named place.

QuestionAnswer
New Python projectsnake_case, PEP 8, no discussion needed
New JavaScript projectcamelCase for code, kebab-case for CSS and URLs
Database schemasnake_case, whatever the application language is
Public JSON APIcamelCase if the consumers are browsers; snake_case if they are Python or Ruby
Existing codebaseWhatever it already uses. Consistency beats correctness here.

Four snake_case mistakes

  • Double underscores from double spaces. Trim the text before converting, or first name becomes first__name, which in Python also has a special meaning.
  • Leading underscores by accident. A name beginning with an underscore signals private in Python and reserved in C. Strip punctuation before converting.
  • Underscores in a URL. Costs you the word separation that a hyphen would give, for no benefit.
  • Converting acronyms letter by letter. A naive converter turns HTTPResponse into h_t_t_p_response. Test on an acronym first.

Every case style in one place. The upper lower case converter handles snake_case, kebab-case, camelCase, PascalCase, Title Case, Sentence case, UPPERCASE and lowercase, with a live word and character count. Free, in your browser.

Renaming a schema: a six-step checklist

Converting an existing database from camelCase to snake_case is the most common reason people arrive at a snake case converter with a hundred names in the clipboard. It is safe if you do it in this order.

  1. Export the current names. Query the information schema for every table and column name and paste the result into the converter above, one per line.
  2. Convert and read the output. The names that need a human are the ones containing acronyms, digits or existing underscores. Fix those by hand before you generate a single statement.
  3. Add the new columns, do not rename in place. A rename is instant but irreversible in the middle of a deployment. Adding a column, backfilling it and dropping the old one later can be stopped at any point.
  4. Update the application in the same release. An ORM that maps createdAt to created_at usually needs one configuration line rather than a hundred annotations.
  5. Search the string literals. Raw SQL in reports, dashboards, scheduled jobs and export scripts is not covered by any refactor tool.
  6. Drop the old columns in a later release, once nothing has referenced them for a full deployment cycle.

Case-only renames need two steps in Git. On macOS and Windows the file system is case insensitive, so renaming UserModel.py to user_model.py can be invisible to Git. Rename to a temporary name first, commit, then rename to the target.

Why the underscore, and not something else

The underscore is a historical accident that turned out well. When programming languages had to choose which punctuation could appear inside an identifier, the underscore was the one character with no arithmetic meaning. The hyphen was already minus, the dot was already member access, the slash was already division.

C adopted it in the early 1970s and every language that borrowed C syntax inherited the rule. Python later made it the official style, Ruby followed, and SQL had independently arrived at the same place because of identifier folding. snake_case is now the default in the two places most likely to outlive an application: the database schema and the configuration file.

Capital letters carry their own history and their own meaning, one that predates computing by centuries. That story is in uppercase unveiled, and the practical rules for capitals in ordinary writing are in the capital letters guide.

A conversion table for mixed codebases

ConceptPython / SQLJavaScriptCSS / URLEnvironment
First namefirst_namefirstNamefirst-nameFIRST_NAME
Created atcreated_atcreatedAtcreated-atCREATED_AT
Max retry countmax_retry_countmaxRetryCountmax-retry-countMAX_RETRY_COUNT
HTTP response codehttp_response_codehttpResponseCodehttp-response-codeHTTP_RESPONSE_CODE
User IDuser_iduserIduser-idUSER_ID

Paste any column of that table into the converter above and it will produce any other column. The camel columns are covered in the camelCase converter guide; for plain text rather than identifiers, use the lowercase converter or the title case converter.

Frequently asked questions

What is snake_case?

snake_case writes a multi-word name in lowercase with underscores between the words: user_first_name, max_retry_count, created_at. It is the standard for variables and functions in Python, Ruby and Rust, and for table and column names in SQL.

What is the difference between snake_case and kebab-case?

The separator. snake_case uses an underscore (user_first_name) and kebab-case uses a hyphen (user-first-name). Underscores are legal inside identifiers; hyphens are not, because a compiler reads them as minus. Use kebab-case for URLs and CSS.

What is SCREAMING_SNAKE_CASE for?

Constants and environment variables: MAX_RETRIES, DATABASE_URL. Capitals signal a value that does not change, a convention inherited from C macros. POSIX also reserves lowercase environment variable names for the shell itself.

How do I convert camelCase to snake_case?

Insert an underscore before every capital letter and lowercase the whole string, taking care with consecutive capitals such as HTTPResponse. The converter on this page does it for a whole list at once.

Should URLs use underscores or hyphens?

Hyphens. Google treats a hyphen as a word separator and an underscore as a joiner, so /red-shoes reads as two words while /red_shoes can read as one. Keep underscores for code and use kebab-case in every public URL.

Why do SQL columns use snake_case?

Because unquoted identifiers are folded by the database: PostgreSQL lowercases them, Oracle uppercases them. A name with no capitals survives that folding unchanged, so it behaves the same on every engine and operating system.

What is the Excel formula for snake_case?

=LOWER(SUBSTITUTE(TRIM(A1)," ","_")). TRIM removes double spaces that would become double underscores, SUBSTITUTE swaps each space for an underscore, and LOWER flattens the capitals.

Is snake_case easier to read than camelCase?

Slightly, for readers new to a codebase, because the underscore is an explicit word boundary while a capital letter is an implicit one. The difference is small and matters far less than being consistent with the language you are writing in.

The short version

snake_case is lowercase words joined by underscores, and it is the standard in Python, Ruby, Rust and SQL. Capitals turn it into SCREAMING_SNAKE_CASE for constants and environment variables. Hyphens turn it into kebab-case, which belongs in URLs, CSS and HTML attributes but never inside an identifier. Databases prefer snake_case because a name without capitals survives identifier folding on every engine, and search engines prefer hyphens because they read them as word boundaries. Trim your input first, watch out for acronyms, and convert between conventions in exactly one place.

Next Post Previous Post