iKit
Guide · 10 min read ·

PascalCase Explained: Class Names and Acronym Rules (2026)

PascalCase looks trivial until an acronym shows up. Here is what each major style guide actually requires for class names, types, and HTTP-shaped words.

PascalCase Explained: Class Names and Acronym Rules (2026)

PascalCase Explained: Class Names and Acronym Rules

PascalCase is the convention where every word in an identifier starts with a capital letter and the separators disappear: user account service becomes UserAccountService. The rule sounds trivial until an acronym shows up. Is it HTTPServer or HttpServer? parseXMLDoc or parseXmlDoc? Different style guides give different answers, and picking the wrong one triggers a linter on your first pull request.

TL;DR

  • PascalCase capitalises every word including the first; camelCase lowercases the first word only.
  • Use it for types, classes, interfaces, enums, and React components — not for variables.
  • Style guides disagree on acronyms: PEP 8 says HTTPServerError, Google Java says XmlHttpRequest.
  • .NET splits the difference: two-letter acronyms stay uppercase (IOStream), longer ones don't.
  • Converting snake_case to PascalCase is easy; converting back safely is not.

What is PascalCase, exactly?

The mechanical definition is short. Split the name into words, uppercase the first character of each word, lowercase the rest, and join with nothing in between. No underscores, no hyphens, no spaces.

PascalCase vs camelCase: what is the difference?

Exactly one character. Both conventions capitalise word boundaries and drop separators; PascalCase also capitalises the very first letter. That single bit of information is doing real work in most languages — it tells the reader (and often the compiler) whether they're looking at a type or a value.

class InvoiceLineItem { }      // PascalCase: a type
const invoiceLineItem = ...    // camelCase: a value

If you're weighing the wider set of options, we compared the three main styles side by side in camelCase vs snake_case vs kebab-case.

Why every style guide calls it something different

The term "CamelCase" on its own is ambiguous — plenty of documentation uses it for both variants, which is why the major guides invented unambiguous names. There is no standards body here; there are four large ecosystems that each picked a label and stuck with it.

Ecosystem Term used Applies to
.NET PascalCasing Types, members, namespaces
Google Java UpperCamelCase Class names, type variables
Python (PEP 8) CapWords Class names, exceptions
Swift UpperCamelCase Types and protocols
Go MixedCaps Exported identifiers

Go is the odd one out in framing: Effective Go calls the convention MixedCaps and ties capitalisation to visibility rather than to kind. An exported Reader is capitalised because it's exported, not because it's a type.

Where the boundary between words actually falls

This is the part people get wrong. Google's Java style guide specifies a near-deterministic recipe: strip punctuation and apostrophes, split into words, lowercase everything including acronyms, then uppercase the first letter of each word. The consequence is that "XML HTTP request" becomes XmlHttpRequest, not XMLHTTPRequest. It also recommends splitting words that only look like single tokens — "AdWords" is two words, so it becomes AdWords in prose-to-identifier conversion but adWords in the lower variant.

The guide also flags genuine ambiguity: "nonempty" and "non-empty" are both valid English, so checkNonempty and checkNonEmpty are both defensible. No algorithm resolves that for you.

Where PascalCase is the required convention

In several places, PascalCase isn't a style preference — the code behaves differently without it.

Why React components must start with a capital letter

JSX uses capitalisation as the signal that distinguishes a user-defined component from a DOM element. <MyButton /> compiles to a call with the MyButton identifier; <myButton /> compiles to a call with the string "myButton", which React then hands to the DOM as an unknown HTML tag. Per the React docs on your first component, component names must start with a capital letter or they will not work.

function ProfileCard() { return <div />; }

<ProfileCard />   // renders the component
<profileCard />   // renders an unknown DOM tag

The failure is silent — no error, just an empty element in the tree. It's one of the most common first-week React bugs.

Types, classes, and interfaces in C#, Java, Swift, and Go

The rule is close to universal for type-like names, even where the terminology differs:

  • C# / .NET — the Framework Design Guidelines require PascalCasing for every public member, type, and namespace name, and camelCasing only for parameters.
  • Java — Google style writes class names in UpperCamelCase, method and field names in lowerCamelCase, and constants in UPPER_SNAKE_CASE.
  • Swift — the API Design Guidelines are blunt: names of types and protocols are UpperCamelCase, everything else is lowerCamelCase.
  • Python — PEP 8 asks for CapWords for class names, and lower_case_with_underscores for functions and variables.
  • TypeScript — follows the JavaScript/Java convention in practice: interfaces, type aliases, enums, and classes in PascalCase.

What PascalCase is not used for

Worth stating explicitly, because over-application is a common review comment. PascalCase does not belong in local variables, function parameters, JSON payload keys, SQL column names, CSS class names, URL path segments, or environment variables. Each of those has its own established convention, and mixing them makes grep and code search worse, not better.

How to handle acronyms in PascalCase

Here is where teams actually argue. The guides do not agree, and each position is internally coherent.

Should HTTP be HTTPServer or HttpServer?

Three genuinely different answers, all from primary sources:

Guide Verdict Example
PEP 8 Keep acronyms uppercase HTTPServerError
Google Java Lowercase, then capitalise XmlHttpRequest
.NET Pascal-case if 3+ letters HtmlTag

PEP 8 states directly that when using acronyms in CapWords you capitalise all the letters of the acronym, so HTTPServerError beats HttpServerError. Google's Java guide reaches the opposite conclusion by applying its lowercase-everything-first algorithm, giving XmlHttpRequest and marking XMLHTTPRequest as incorrect.

Neither is wrong. PEP 8 optimises for the acronym staying visually intact; Google optimises for a mechanical rule that produces one answer every time, which matters when you have automated tooling and a very large codebase.

The two-letter acronym exception in .NET

Microsoft's rule is the most nuanced of the three. PascalCasing capitalises the first character of each word including acronyms over two letters in length — so HtmlTag, not HTMLTag. But a special case is carved out for two-letter acronyms, where both letters stay capitalised: IOStream. In the camelCase variant, a leading two-letter acronym goes fully lowercase: ioStream.

The same document warns against a related trap: closed-form compound words count as a single word. It's Endpoint, not EndPoint; Hashtable, not HashTable; Filename is wrong and FileName is right, because "file name" is two words in a dictionary but "hashtable" is one. If you're unsure, check a current dictionary rather than your instinct.

Swift's rule: uniformly up- or down-cased

Swift takes a fourth position. Acronyms that normally appear in all caps in English should be uniformly upper- or lowercased according to the surrounding convention — you get utf8Bytes and UTF8.CodeUnit, or userSMTPServer and SecureSMTPServer. Acronyms that have become ordinary words are treated as ordinary words: radarDetector, enjoysScubaDiving. It's a readability rule rather than a mechanical one, which is very Swift.

A practical policy

If your team is arguing about this in a code review, the useful move is to pick the convention your language's dominant linter already enforces and stop. Ruff and Flake8 will nudge you toward PEP 8; dotnet format and Roslyn analysers toward the Microsoft rules; google-java-format toward the Google recipe. Consistency inside one repository is worth far more than any of the three positions being "right".

How to convert snake_case to PascalCase in JavaScript

Most real conversions start from an existing name, not from prose. The safe approach is to split on explicit separators only, then capitalise.

const toPascal = (s) =>
  s
    .split(/[\s_\-]+/)
    .filter(Boolean)
    .map((w) => w[0].toUpperCase() + w.slice(1))
    .join("");

toPascal("user_account_service");
// "UserAccountService"
toPascal("api-response-cache");
// "ApiResponseCache"

Why this breaks on acronyms and digits

That function does one thing well: it handles snake_case, kebab-case, and space-separated input. What it cannot do is guess. Feed it parse_HTML_doc and you get ParseHTMLDoc — correct under PEP 8, wrong under Google Java style. Feed it an already-camelCase input like getUserID and it returns GetUserID unchanged, because there are no separators to split on.

Digits are the other landmine. Is oauth2Provider one word plus a digit, or two? Google's guide notes that in rare cases like multipart version numbers you may need underscores to separate adjacent digits, since numbers have no case. Any converter that promises to handle this without configuration is guessing.

The pragmatic answer: convert with a tool, then eyeball the acronyms. The iKit Case Converter runs entirely in your browser, converts between PascalCase, camelCase, snake_case, kebab-case and CONSTANT_CASE, and lets you fix acronym boundaries by hand before you paste the result. Nothing is uploaded anywhere.

Converting every key in a JSON payload

A .NET API returning PascalCase keys to a JavaScript client is a familiar mismatch:

{
  "UserId": 42,
  "DisplayName": "Ada",
  "LastLoginAt": "2026-09-09T08:15:00Z"
}

Do the transformation once, at the boundary — in a fetch wrapper or a serializer setting — rather than sprinkling data.UserId ?? data.userId through your components. If you're inspecting a payload before writing that mapping, paste it into the JSON Decoder to see the key structure formatted, and use the Diff Checker to compare the pre- and post-conversion shapes so you can confirm no key silently disappeared.

PascalCase pitfalls that break builds

Two failure modes show up repeatedly, and neither is about aesthetics.

Case-insensitive filesystems and PascalCase filenames

macOS ships with a case-insensitive filesystem by default; Linux CI runners are case-sensitive. If a developer renames usercard.tsx to UserCard.tsx and Git records the change as a no-op locally, the import from "./UserCard" works on the laptop and fails in CI with a module-not-found error. The fix is git mv through a temporary name, but the prevention is a lint rule that enforces one filename convention per project.

Names that differ only by case

The .NET guidelines are explicit that publicly visible names must not differ by case alone, because not every language targeting the runtime is case-sensitive. The same reasoning applies well beyond .NET: environment variable lookups, HTTP header handling, and most SQL identifier resolution are case-insensitive somewhere in the stack. A User type and a user type in the same namespace is a bug waiting for a different consumer.

Validating a PascalCase identifier

If you need to enforce the convention in a script or a pre-commit hook, a simple anchored pattern covers the common case:

^[A-Z][a-z0-9]*([A-Z][a-z0-9]*)*$

That accepts UserAccountService and rejects userAccountService, User_Account, and USERACCOUNT. It also rejects HTTPServer, which is the point if your house style is Google-flavoured — and the problem if it isn't. Test the variant your team actually wants against real identifiers in the Regex Tester before you wire it into CI, because a naming lint that fires on legitimate names gets disabled within a week.

References

Related on iKit

Related posts