Guides / camelCase, snake_case, and kebab-case

camelCase, snake_case, and kebab-case

By Alpha Elite Digital. Published . Updated .

A space is legal in a headline and illegal inside most identifiers. camelCase, snake_case, and kebab-case are three ways to join the words anyway. This page says which join JavaScript, Python, CSS, and SQL expect, and which public style guide says so.

Title Case and Sentence case change letters and leave underscores and hyphens where they are. Those rules are on Title Case rules and Sentence case vs Title Case, and the buttons are on the home converter. Identifier buttons are on the developer case converter. This page is the choice of shape.

One phrase, five shapes

Take the words user profile image. The developer case converter emits these five strings from that phrase. PascalCase and CONSTANT_CASE are in the list because the guides below require them for classes and constants. The title of this page stays with the three joins people mix up.

user profile image camelCase: userProfileImage PascalCase: UserProfileImage snake_case: user_profile_image kebab-case: user-profile-image CONSTANT_CASE: USER_PROFILE_IMAGE

Same words. The join and the capitals are the only change. The sections below name the document for each one.

The nicknames disagree

PEP 8's naming-styles list calls CapitalizedWords "CapWords, or CamelCase," from the bumpy look of the letters. In that same list, mixedCase starts with a lowercase letter. MDN's JavaScript code style swaps the nicknames: PascalCase for a class, camelCase for a property, a method, or an instance. Google's JavaScript style guide says UpperCamelCase and lowerCamelCase. On this page, camelCase means a lowercase first word, and PascalCase means a capital on every word. A quote below keeps the source's own word.

JavaScript

The language does not require a case style. MDN's object-names section uses PascalCase for a class and camelCase for properties, methods, and instances. The example on that page is a class Person and an instance hanSolo. Google's section 6 splits the same idea by kind of name:

Section 6.3 defines the conversion: lowercase the whole phrase, including acronyms, then capitalize each word, or each word except the first. In the correct column, "XML HTTP request" is xmlHttpRequest, "new customer ID" is newCustomerId, and "supports IPv6 on iOS?" is supportsIpv6OnIos. XMLHTTPRequest and newCustomerID are the incorrect column.

Google's rows, and this site's button XML HTTP request xmlHttpRequest matches new customer ID newCustomerId matches supports IPv6 on iOS supportsIpv6OnIOs Google's row is supportsIpv6OnIos

The first two lines are the developer case converter on camelCase. The third line is the same button, and it disagrees with Google's row. The tool page explains the split. Change the last three letters if the name has to match the table. A hyphen is also minus, so user-profile-image is a subtraction, not a JavaScript binding. It fits CSS, an HTML attribute, or a URL.

Python

PEP 8 is the naming document for the Python standard library. Google's Python style guide says, in general, to follow those PEP 8 naming conventions.

Function names should be lowercase, with underscores between words when that helps reading. Variables follow the same rule. mixedCase is allowed only where that is already the local style. PEP 8 names threading.py. user_profile_image is the ordinary new function.

Class names use CapWords, so the class is UserProfileImage. Acronyms inside CapWords stay fully capital. PEP 8 prefers HTTPServerError over HttpServerError, and Google's Python guide repeats that sentence. PascalCase on HTTP server error returns HttpServerError. For an exception class under PEP 8, restore the acronym by hand.

HTTP server error PEP 8 class: HTTPServerError PascalCase button: HttpServerError snake_case button: http_server_error

Module-level constants are written in capitals with underscores between words. PEP 8's examples are MAX_OVERFLOW and TOTAL. Choosing CONSTANT_CASE on MAX_OVERFLOW leaves MAX_OVERFLOW. Choosing it on the words "max overflow" produces the same string.

Modules should be short and all lowercase. An underscore is fine in a module name when it helps. Packages should also be short and lowercase, and PEP 8 discourages underscores there, so userprofile rather than user_profile.

One leading underscore marks a non-public method or instance variable. The converter treats underscores as boundaries, so _user_id comes back as user_id. Put the underscore back if the name is non-public. PEP 8 also describes two leading underscores for name mangling. Google's Python guide prefers a single underscore. The button emits neither prefix.

CSS

CSS property names are already hyphenated. background-color is the property the language ships, which is why the kebab-case button on "background color" is the string people already type in a style rule.

Google's HTML/CSS style guide says to use only lowercase. That rule covers element names, attributes, attribute values other than text, selectors, properties, and property values. Strings are the exception they name. The same guide's class-name delimiters separate words with a hyphen. The recommended selectors are .video-id and .ads-sample. .demoimage fails the rule because the words are glued together. .error_status fails it because the join is an underscore.

An id that you actually need should contain a hyphen too. The id-attributes section uses user-profile rather than userProfile, so the value does not look like a JavaScript identifier. For this phrase the class is .user-profile-image and the variable beside it is userProfileImage.

MDN's custom-properties page notes that the names are case sensitive. --my-color and --My-color are two properties. A custom property for this phrase is --user-profile-image. Match a file that already has its own pattern. The hyphenated form is the one Google's guide asks for, and it is what the kebab-case button emits.

SQL

Google's style-guide index lists JavaScript, Python, HTML/CSS, and a set of other languages. It does not list a SQL guide. SQL also has no PEP 8 for table and column names. The document this section can cite is PostgreSQL's lexical structure.

In PostgreSQL, key words and unquoted identifiers are case-insensitive, because unquoted names are folded to lower case. FOO, foo, and "foo" are the same identifier. "Foo" and "FOO" are different from those and from each other. The docs call this fold incompatible with the SQL standard, which folds unquoted names to upper case, and they advise you to always quote a given name or never quote it.

The same page shows key words in upper case and names in lower case: UPDATE my_table SET a = 5;. That is a keyword habit. snake_case is the identifier form that still means something after the fold, because a space is illegal and a capital does not survive.

Unquoted PostgreSQL names user_profile_image stays user_profile_image userProfileImage becomes userprofileimage MAX_OVERFLOW is the same name as max_overflow "userProfileImage" stays mixed case, and every statement must quote it

The first line is the snake_case button. The second line is what the fold does to camelCase if you paste it without quotes. The third line is why a CONSTANT_CASE constant and a snake_case column can collide: unquoted, they are one identifier. Quoted "MAX_OVERFLOW" is a different name. The converter does not add those quotes. You add them, and you keep them, if mixed case is a requirement someone imposed on the schema.

This page does not state a default for MySQL or SQL Server. Unquoted case on those servers depends on the server settings. Match the schema you already have, and quote consistently inside it.

Across a boundary

One fact often crosses three files. "created at" is created_at in a Python function, because that is the PEP 8 shape. It is createdAt on a JavaScript object, because that is lowerCamelCase in Google's guide and camelCase in MDN's. A class name for the same words, under Google's hyphen rule, is created-at. None of those three is a translation mistake. They are three documents applied to one phrase. The developer case converter produces all three from created at.

created at Python function: created_at JavaScript field: createdAt CSS class: created-at

A URL is a fourth document. Google Search Central recommends hyphens between words in a URL. Underscores, they write, already mean "keep this together" in programming languages, and the example they give is format_date. The faucet headline on this site becomes the slug how-to-fix-a-leaky-faucet, which is the kebab-case button on "how to fix a leaky faucet". Title Case for that headline is the home converter, then Title Case rules.

What you still fix by hand

The converter uses one word list. The style guides do not.

Digits, apostrophes, and names such as XMLHttpRequest and user2FA are worked on the developer case converter page.

Use the converter

Open the developer case converter. Paste a phrase or a whole identifier, click camelCase, PascalCase, snake_case, kebab-case, CONSTANT_CASE, or dot.case, then copy. The split runs in the browser. Nothing in the box is uploaded for the conversion. Select a whole name when the surrounding sentence should stay.

The home converter is the other tool. Its four buttons change letter case and leave separators alone. Feature_Flag_Key through lower case is feature_flag_key, which is the job described on When to use each case. Building the separators from ordinary words is this guide, then the developer case page.

Sources