Back to Blog
Tutorialstextformattingprogramming

Text Case Conversion: camelCase, snake_case, and Beyond

Complete guide to naming conventions. Learn camelCase, PascalCase, snake_case, kebab-case, and when to use each in JavaScript, Python, CSS, and more.

Loopaloo TeamAugust 5, 202512 min read

Every identifier a programmer writes is a small act of language design. The conventions that govern whether we write getUserName, get_user_name, or get-user-name are not arbitrary aesthetic preferences — they are the product of decades of language evolution, community negotiation, and hard-won ergonomic insight. Understanding where these conventions come from, why each language adopted its particular style, and what pitfalls lurk in automated conversion between them is essential knowledge for any developer who works across multiple ecosystems. Tools like the Text Case Converter and Text Formatter on Loopaloo make the mechanical transformation trivial, but the intellectual framework behind that transformation is what this guide aims to provide.

The Origin of Naming Conventions in Programming

In the earliest days of computing, identifier naming was constrained by brutal technical limitations. FORTRAN ignored spaces entirely and was case-insensitive, so ICOUNT and icount were the same symbol. COBOL used hyphens as word separators — a convention that persists in HTTP headers to this day. Assembly programmers, working with six-character label limits on many mainframes, developed a culture of terse abbreviation that had no room for multi-word conventions at all.

The idea that identifier casing could serve as a semantic signal — that the shape of a name could communicate its role — emerged gradually as languages grew more expressive and codebases grew larger. By the 1980s, the major conventions we recognize today had crystallized, each one carrying the fingerprint of the language or community that popularized it.

camelCase and Its Roots in Smalltalk

The convention of joining words by capitalizing each subsequent word while keeping the first letter lowercase — firstName, getUserById, isValidEmail — is universally called camelCase, a name coined in the 1990s but describing a practice that dates back to Smalltalk in the late 1970s. Smalltalk was designed by Alan Kay's team at Xerox PARC as a language in which everything was an object and messages were sent between them. In Smalltalk, method names like printString and addSubView: were the norm, and because the language had no underscores in its identifier grammar and treated hyphens as minus operators, concatenating words with medial capitals was the only natural option.

When Brendan Eich created JavaScript in 1995, he drew on Java's syntax, which had itself inherited camelCase from C and Smalltalk's influence on object-oriented culture. Java's convention of camelCase for methods and variables and PascalCase for classes became the template for JavaScript, TypeScript, and eventually the entire web development ecosystem. Today, camelCase dominates JSON property names, JavaScript and TypeScript variables and functions, and Java methods. Its compactness is its virtue — no separator characters means shorter identifiers — though this comes at the cost of reduced readability for very long compound names.

PascalCase and the Pascal Language

PascalCase, in which every word begins with a capital letter including the first — UserService, HttpRequest, StringBuilder — takes its name from Niklaus Wirth's Pascal language, designed in 1970 as a teaching tool for structured programming. Pascal's standard library used this convention for type names and procedure names alike, and when Anders Hejlsberg carried its spirit into Turbo Pascal and later into Delphi and C#, PascalCase came with him.

In C#, PascalCase is the dominant casing for nearly everything public — methods, properties, events, and classes all use it — making it perhaps the most PascalCase-heavy language in mainstream use. In the broader ecosystem, PascalCase has settled into its enduring role as the convention for type-level constructs: classes in Java, Python, Ruby, and Go; React and Vue components in JavaScript; interfaces and type aliases in TypeScript. The visual prominence of the initial capital letter serves as a reliable signal that the identifier represents a type or constructor rather than a value or function.

snake_case and Python's PEP 8

The underscore-separated, all-lowercase convention — first_name, get_user_by_id, created_at — is older than most programmers realize. C programmers used it from the beginning, and the standard C library is full of functions like str_copy and mem_set (though many are compressed to strcpy and memset). But it was Python that elevated snake_case to a defining cultural marker through PEP 8, the style guide authored by Guido van Rossum and Barry Warsaw in 2001.

PEP 8's prescription is unambiguous: functions, methods, variables, and module names should use snake_case, while classes use PascalCase and constants use SCREAMING_SNAKE_CASE. The reasoning is rooted in readability — Python's founding philosophy — and the empirical observation that underscores create clear visual word boundaries that remain legible even in long identifiers like calculate_monthly_interest_rate. Ruby adopted the same convention, as did Rust, and it remains the dominant style in SQL and database schemas. PostgreSQL identifiers, table names, and column names are almost universally snake_case, making it the lingua franca of data modeling.

kebab-case in CSS and URLs

When words are separated by hyphens and rendered entirely in lowercase — user-profile, main-container, button-primary — the result is called kebab-case, a name that evokes the visual image of words skewered on a hyphen. This convention dominates CSS, where class names like .nav-header and custom properties like --primary-color are the norm. It also rules URL slugs, npm package names, and command-line flags.

The reason kebab-case thrives in CSS and URLs but not in programming languages is straightforward: most languages interpret a hyphen as the minus operator, so user-profile would be parsed as "user minus profile." CSS, HTML attributes, and URLs have no such constraint, which freed them to adopt the most visually readable separator character. The BEM methodology — Block, Element, Modifier — builds on kebab-case by layering additional conventions with double underscores and double hyphens (block__element--modifier), creating a structured naming system that scales to large stylesheets.

SCREAMING_SNAKE_CASE for Constants

The all-uppercase, underscore-separated convention — MAX_RETRIES, API_BASE_URL, HTTP_STATUS_OK — serves a single, powerful purpose: it screams "this value does not change." The convention traces back to C preprocessor macros, where #define MAX_BUFFER_SIZE 1024 was the standard pattern, and the uppercase signaled to the programmer that this was not a variable but a compile-time substitution.

Nearly every language has adopted SCREAMING_SNAKE_CASE for constants and configuration values. JavaScript uses it for module-level constants, Python's PEP 8 prescribes it for module-level constants, Java uses it for static final fields, and environment variables (DATABASE_URL, JWT_SECRET) are universally screaming snake. The convention is so ingrained that seeing an all-caps identifier triggers an immediate cognitive response: this is a fixed value, do not reassign it.

Why Each Language Chose Its Convention

The naming conventions of programming languages are not arbitrary — they are shaped by syntax constraints, historical lineage, and community values. JavaScript uses camelCase because it borrowed Java's syntax, and Java used camelCase because its designers came from the C and Smalltalk traditions. Python uses snake_case because Guido van Rossum valued readability above all else and believed underscores produced the clearest word boundaries. Go uses PascalCase for exported identifiers and camelCase for unexported ones because the language designers wanted visibility to be encoded directly in the name's casing rather than in a keyword like public or private — a radical design choice that makes casing functionally significant rather than merely conventional.

C# uses PascalCase for virtually all public members because Anders Hejlsberg, who came from the Pascal and Delphi tradition, carried that convention forward and Microsoft's .NET framework guidelines codified it. Ruby uses snake_case because Yukihiro Matsumoto designed Ruby to be pleasant to read and write, treating code as prose where underscored words feel natural. Rust chose snake_case for values and functions and PascalCase for types, following Python and C's example, and its compiler actually emits warnings if you deviate from the convention — making casing part of the language's enforcement mechanism rather than a mere suggestion.

Compound Word Edge Cases

Automated case conversion works beautifully for simple multi-word identifiers, but it stumbles on compound words that contain acronyms or initialisms. Consider HTTPSConnection: is this two words (HTTPS + Connection) or three (HTTP + S + Connection)? A naive algorithm that splits on uppercase-to-lowercase transitions would produce h-t-t-p-s-connection in kebab-case — obviously wrong. Similarly, XMLParser might become x-m-l-parser instead of the intended xml-parser.

The industry has gradually converged on the recommendation to treat acronyms as single words with only their first letter capitalized in PascalCase and camelCase contexts: HttpsConnection rather than HTTPSConnection, XmlParser rather than XMLParser. Google's Java style guide, Microsoft's .NET guidelines, and Apple's Swift API design guidelines all endorse this approach. The reasoning is pragmatic: HTTPSConnection is ambiguous at the boundary between the acronym and the next word, while HttpsConnection parses unambiguously. When using the Text Case Converter, being aware of these edge cases helps you anticipate where manual adjustment might be necessary after an automated transformation.

Unicode Challenges in Case Conversion

Case conversion seems simple until you encounter the full complexity of Unicode. The most notorious example is the Turkish İ problem. In most locales, the uppercase form of i is I, and the lowercase form of I is i. In Turkish (and Azerbaijani), however, the uppercase form of i is İ (capital I with a dot above), and the lowercase form of I is ı (dotless lowercase i). This means that a case-insensitive comparison of "FILE" and "file" produces different results depending on the locale — a bug that has plagued Java applications, .NET services, and web frameworks for decades.

German presents its own challenge with the character ß (Eszett). For centuries, ß had no uppercase form — it was uppercased as SS. In 2017, the German orthographic council officially introduced (capital Eszett), but adoption is uneven and most software still converts ß to SS. This means that uppercasing straße (street) produces STRASSE, a conversion that changes the string's length — something that many algorithms do not expect. Other Unicode edge cases include the Greek final sigma (ς vs σ), which changes form depending on its position in a word, and ligatures like that decompose into two characters when uppercased.

For developers building case conversion tools, the lesson is clear: never use naive ASCII-only toUpperCase() and toLowerCase() implementations. Always specify a locale when one is relevant, use Unicode-aware libraries, and test with strings that go beyond the ASCII range. The Text Formatter handles these transformations with proper Unicode awareness, but understanding why it matters will save you from subtle, locale-dependent bugs in your own code.

Programmatic Conversion Strategies

Converting between case conventions programmatically requires solving two sub-problems: first, decompose the input string into its constituent words; second, reassemble those words in the target convention. The decomposition step is where most of the complexity lives. A robust algorithm must handle inputs that might already be in any convention — camelCase, PascalCase, snake_case, kebab-case, SCREAMING_SNAKE_CASE, or even plain space-separated text.

The most reliable approach is a multi-step decomposition: first, insert a boundary before each uppercase letter that follows a lowercase letter (to split camelCase and PascalCase); then insert a boundary before any uppercase letter that is followed by a lowercase letter and preceded by another uppercase (to correctly handle acronyms like XMLParserXML, Parser); then split on underscores, hyphens, and whitespace. Once you have a clean array of lowercase words, reassembly is trivial — join with underscores for snake_case, with hyphens for kebab-case, capitalize first letters for PascalCase, and so on.

Libraries like change-case in the npm ecosystem and inflection in Python provide battle-tested implementations of these algorithms. For one-off conversions during development, the Loopaloo Text Case Converter lets you paste text and instantly see the result in every major convention, which is particularly useful when you are porting code between languages or renaming identifiers across a codebase.

When to Break Convention

Rules exist to serve communication, and there are legitimate reasons to deviate from a language's standard naming convention. The most common is interoperability: if your Python service consumes a JSON API that uses camelCase keys, you may choose to keep those keys in camelCase in your Python code rather than converting them at the boundary, especially in a small script where the overhead of translation outweighs the benefit of consistency. Similarly, if your JavaScript frontend talks to a database with snake_case column names, you might propagate snake_case into your data layer to avoid a mapping step.

Another valid reason to break convention is when a domain-specific term has an established casing. Writing pH in a chemistry application is more correct than ph or PH, and forcing it into camelCase (phLevel) loses meaningful information. Legacy codebases present a pragmatic case as well — if an existing project consistently uses a non-standard convention, matching that convention is almost always better than introducing a second style.

The key principle is that consistency within a project trumps adherence to a language-wide standard. A codebase that uniformly uses one convention, even an unusual one, is easier to navigate than a codebase where half the files follow one style and half follow another. When you do need to convert between styles — whether refactoring a codebase, migrating between languages, or normalizing an API contract — reach for the Text Case Converter and the Text Formatter to handle the mechanical work, and reserve your cognitive energy for the decisions that matter: choosing names that are clear, precise, and expressive.

Related Tools

Related Articles

Try Our Free Tools

200+ browser-based tools for developers and creators. No uploads, complete privacy.

Explore All Tools