camelCase vs snake_case vs kebab-case: guia 2026 de convenções de nomenclatura
userID ou userId? user_profile ou userProfile? URLs com - ou _? São as perguntas que travam revisões de PR cinco vezes por dia. A resposta não é “preferência pessoal” — cada linguagem mainstream e cada padrão web tem uma regra consolidada, e ver todas elas em uma única página resolve a discussão.
Este guia cobre os seis cases que você realmente encontra em código (camelCase, PascalCase, snake_case, kebab-case, CONSTANT_CASE, dot.case / path/case / Header-Case), uma matriz de decisão para sete linguagens, o debate parseUrl-vs-parseURL sobre acrônimos com dados reais do GitHub, o argumento de SEO a favor de URLs em kebab-case e as seis armadilhas que pegam quem faz conversão automática entre cases. Se você quiser ver de uma só vez as 15 saídas de case para qualquer string, o Conversor de Maiúsculas e Minúsculas renderiza tudo ao vivo no navegador.
Os seis cases num relance
Antes de qualquer comparação, aqui está a cola. Imprima, cole no wiki da equipe ou deixe aberta em uma aba.
| Estilo de case | Exemplo | Uso típico | Origem / popularizador |
|---|---|---|---|
| camelCase | userProfileImage | Variáveis e métodos em JS, TS, Java, Swift | Smalltalk → Java |
| PascalCase | UserProfileImage | Classes, componentes React/Vue, tipos TS | Linguagem Pascal |
| snake_case | user_profile_image | Python, Ruby, Rust, colunas SQL | C / Unix primitivo |
| kebab-case | user-profile-image | Classes CSS, slugs de URL, atributos HTML | Lisp / web moderna |
| CONSTANT_CASE | USER_PROFILE_IMAGE | Variáveis de ambiente, constantes, macros | Macros C / env Unix |
| dot.case | user.profile.image | Pacotes Java, paths MongoDB, chaves TOML | Convenção de namespace |
| path/case | user/profile/image | Paths de URL, filesystem, refs Git | Paths Unix |
| Header-Case | User-Profile-Image | Nomes de header HTTP/1.1 (canônico) | RFC 2616 |
Oito linhas para seis cases “reais” — dot.case, path/case e Header-Case compartilham a mesma tokenização subjacente com separadores diferentes, e é por isso que a maioria das bibliotecas de case trata os três como uma única família.
Cada case em profundidade
camelCase: o padrão de JS/Java
camelCase foi ideia do Smalltalk, mas foi o Java que exportou a convenção para o resto da indústria. As convenções de código Java da Sun em 1995 transformaram firstName, getUserProfile e xmlParser na grafia padrão, e cada linguagem que queria parecer Java — JavaScript, ActionScript, Swift, Kotlin, Dart — herdou o mesmo formato.
Regra: primeira palavra em minúsculas, inicial de cada palavra seguinte em maiúscula, separador removido por completo. Sem underscores, sem hifens, sem espaços. O nome “camelCase” vem do contorno cheio de corcovas que as letras maiúsculas formam no meio de um mar de minúsculas.
Dois casos que costumam sair errados: marcas que começam em minúscula (iPhone, eBay, iOS) — quando uma delas aparece em código, não force a maiúscula no i; escreva como a marca escreve e aceite o identificador um pouco esquisito. E os acrônimos — detalhados mais adiante.
PascalCase: classes e componentes
PascalCase é camelCase com a primeira letra maiúscula. Alguns guias de estilo chamam de “UpperCamelCase” justamente por isso. A linguagem Pascal usava esse formato nos anos 1970 e o nome ficou.
Onde aparece: nomes de classe em toda linguagem OO da família C (Java, C#, C++, Kotlin, Swift, TypeScript), nomes de componentes React/Vue/Angular, aliases de tipo e interfaces TypeScript (type UserProfile, interface AuthState) e nomes de módulo/arquivo em alguns ecossistemas (UserService.cs em C#).
Por que um case separado só para classes? É um sinal visual. Quando você lê new userProfile() versus new UserProfile(), o segundo é reconhecido como um tipo e o primeiro como uma chamada de função problemática. Linguagens que misturam namespaces de valor e de tipo se apoiam na capitalização para desambiguar.
snake_case: Python, Ruby, Rust, SQL
snake_case é mais antigo do que muita gente imagina — C e o Unix primitivo já usavam nomes no estilo errno_h e fopen_s porque os teclados dos terminais PDP-11 deixavam o underscore fácil e a capitalização Pascal incômoda. Python adotou snake_case como convenção oficial via PEP 8, a comunidade Ruby chegou à mesma escolha organicamente, e Rust transformou snake_case no padrão obrigatório do compilador, com um lint que reclama se a variável for userId em vez de user_id.
Regra: tudo em minúsculas, palavras unidas por underscore. user_profile_image, parse_html, max_retries.
A perspectiva do banco de dados é a parte que a maioria dos tutoriais de linguagem pula. Praticamente qualquer ORM SQL — SQLAlchemy, Hibernate, Sequelize, TypeORM, Active Record — usa snake_case por padrão para nomes de coluna, independentemente da convenção da linguagem hospedeira. O motivo é portabilidade: PostgreSQL converte identificadores não citados para minúsculas, MySQL no Linux é sensível a maiúsculas/minúsculas, MySQL no macOS/Windows é insensível, SQLite trata nomes de coluna como strings opacas. snake_case é a única grafia que sobrevive a esses cenários sem precisar de aspas.
kebab-case: a escolha da web
A web convergiu para kebab-case em tudo que é visível ao usuário: classes CSS (.user-profile-image), slugs de URL (/blog/naming-conventions-guide), atributos HTML customizados (data-user-id), nomes de tag de Web Components (<user-card>, que o próprio spec exige que contenha um hífen).
O nome em si aparece em umas oito variantes nos documentos antigos — “dash-case”, “spinal-case”, “lisp-case”, “skewer-case”, “hyphen-case”. Todos significam a mesma coisa. “kebab-case” foi o que pegou por causa de uma piada antiga no Stack Overflow comparando as palavras a pedaços de carne em um espeto.
Uma regra não óbvia: nomes de classe HTML e CSS são insensíveis a maiúsculas/minúsculas na prática, mas a grafia canônica é em minúsculas. .User-Profile funciona na maioria dos navegadores, mas quebra ferramentas server-side que fazem hash de nomes de classe e confunde quem revisa o código. Mantenha em minúsculas.
CONSTANT_CASE: variáveis de ambiente e macros
CONSTANT_CASE (às vezes chamado SCREAMING_SNAKE_CASE nos círculos Rust) é o sinal universal de “este valor nunca muda em tempo de execução”. MAX_RETRIES, API_KEY, DEFAULT_TIMEOUT_MS. Cada linguagem tem uma convenção para isso, e qualquer sistema de CI, runtime de container e shell espera variáveis de ambiente nesse formato (DATABASE_URL, NODE_ENV, PATH).
Armadilha: a palavra-chave const do JavaScript não significa “use CONSTANT_CASE”. const result = await fetch(url) é camelCase perfeitamente correto. Reserve CONSTANT_CASE para constantes semânticas de verdade — valores que seriam declarados com #define em C, o tipo de coisa onde alterar o valor em tempo de execução seria um bug. MAX_RETRIES = 3 se enquadra. result não.
dot.case, path/case, Header-Case
Três irmãos que compartilham o mesmo tokenizador com separadores diferentes.
dot.case representa chaves hierárquicas: pacotes Java (com.example.service), paths de campo do MongoDB (user.profile.image), chaves de configuração TOML/INI ([database.primary]), paths de método do Lodash (_.get(obj, 'user.profile.image')). Ao ler uma string em dot.case, você deve enxergar “namespace, namespace, folha”.
path/case representa localizações literais: paths de URL, paths de filesystem, refs Git (feature/add-auth). A escolha entre pontos e barras tem significado — barras sinalizam “isto é uma coisa real em algum lugar”, pontos sinalizam “isto é um rótulo”.
Header-Case é a convenção do HTTP/1.1: Content-Type, Access-Control-Allow-Origin, X-Forwarded-For. Tecnicamente os headers HTTP/1.1 são insensíveis a maiúsculas/minúsculas (RFC 2616), então content-type funciona, mas frameworks, documentação e desenvolvedores esperam a grafia Header-Case. HTTP/2 e HTTP/3 mudaram isso — a RFC 7540 §8.1.2 obriga nomes de header em minúsculas na transmissão para simplificar a compressão de headers (HPACK). Na prática, isso é invisível para o código da aplicação porque cliente e servidor HTTP/2 normalizam para você, mas se você algum dia inspecionar um frame HTTP/2 cru, os headers virão em kebab-case totalmente em minúsculas.
Matriz de decisão para sete linguagens
A forma mais rápida de encerrar uma discussão sobre nomenclatura é olhar o que a biblioteca padrão da linguagem faz. Aqui está a matriz.
| Linguagem | Variável | Função | Classe | Constante | Nome de arquivo | Coluna DB |
|---|---|---|---|---|---|---|
| Python (PEP 8) | snake_case | snake_case | PascalCase | CONSTANT_CASE | snake_case.py | snake_case |
| JavaScript/TS | camelCase | camelCase | PascalCase | CONSTANT_CASE | kebab-case.js | snake_case |
| Go | camelCase* | PascalCase** | PascalCase | mixedCase*** | snake_case.go | snake_case |
| Rust | snake_case | snake_case | PascalCase | SCREAMING_SNAKE | snake_case.rs | snake_case |
| Java | camelCase | camelCase | PascalCase | CONSTANT_CASE | PascalCase.java | snake_case |
| C# | camelCase† | PascalCase | PascalCase | PascalCase | PascalCase.cs | snake_case |
| SQL | n/a | snake_case | n/a | n/a | n/a | snake_case |
*Go: inicial minúscula significa não exportado (privado ao pacote); inicial maiúscula significa exportado (público). O compilador impõe essa regra.**Go: funções exportadas são PascalCase (http.NewRequest); funções privadas ao pacote são camelCase (http.parseHeader).***Go: constantes seguem a mesma regra de capitalização exportado/não-exportado —MaxRetriespara exportado,maxRetriespara privado. Go evita CONSTANT_CASE deliberadamente.†C#: variáveis locais e campos privados são camelCase (algumas codebases prefixam campos com_:_userName); propriedades públicas, métodos e tipos são PascalCase.
Três camadas que atravessam todas as linguagens:
HTML e CSS: nomes de classe e IDs são kebab-case (<div class="user-profile-card">). Atributos HTML customizados são kebab-case com prefixo data- (data-user-id). Propriedades CSS inline são kebab-case (background-color); os equivalentes no DOM em JS são camelCase (element.style.backgroundColor).
HTTP: nomes de header em saída são Header-Case para HTTP/1.1 ('Content-Type': 'application/json') e kebab-case em minúsculas na transmissão HTTP/2. A maioria das bibliotecas de fetch aceita qualquer grafia e normaliza internamente.
Variáveis de ambiente: CONSTANT_CASE em qualquer ambiente — Node, Python, Go, Rust, Bash, Docker, Kubernetes. A convenção do arquivo .env é a mesma: DATABASE_URL=postgres://....
Tratamento de acrônimos: Google vs Microsoft
Esta é a pergunta de nomenclatura mais controversa em revisão de código. Deve ser parseUrl ou parseURL? userId ou userID? HtmlParser ou HTMLParser? XmlHttpRequest ou XMLHttpRequest?
Existem duas escolas, e ambas têm autoridade real do mundo de produção por trás.
Tratar acrônimo como palavra (Google, Apple, JS moderno): parseUrl, userId, HtmlParser. O Google JavaScript Style Guide §5.3 recomenda explicitamente. As Apple Swift API Design Guidelines fazem o mesmo. Os pacotes lodash e change-case produzem essa saída por padrão. O argumento é a estabilidade de ida e volta: parseUrl tokeniza limpo em parse / url, converte para parse_url e volta para parseUrl sem perda de informação. parseURL tokeniza em parse / URL, converte para parse_u_r_l em um tokenizador ingênuo ou para parse_url em um tokenizador ciente de acrônimos — mas aí parse_url não consegue decidir se volta para parseUrl ou parseURL, porque a grafia em minúsculas perdeu o sinal do acrônimo.
Preservar a capitalização do acrônimo (Microsoft, .NET, Java antigo): parseURL, userID, HTMLParser, XMLHttpRequest. As Microsoft .NET Naming Guidelines limitam essa abordagem a acrônimos de 2-3 letras (IO, URL, XML) e usam tratar-como-palavra para os mais longos (Html ficaria preservado em maiúsculas sob a leitura estrita, mas a Microsoft escreve HtmlAgilityPack na prática). A API Win32, a .NET BCL e a maior parte do código Java anterior a 2010 seguem por aí. A leitura soa mais natural para falantes de inglês — parseURL parece “parse U-R-L” — ao custo da propriedade de ida e volta.
A PEP 8 do Python recomenda nominalmente tratar-como-palavra, mas a biblioteca padrão do Python é historicamente inconsistente: http.server.HTTPServer e xml.etree.ElementTree preservam acrônimos, enquanto json.JSONDecoder faz o mesmo. Adições mais recentes (pathlib.PurePath, dataclasses) pendem para tratar-como-palavra. A linha da PEP 8 é: siga o estilo do código ao redor.
Uma amostragem feita em 2026 no corpus público do GitHub (a amostra bigquery-public-data.github_repos no BigQuery, filtrada para arquivos TypeScript e JavaScript de repositórios com 1k+ estrelas) mostra uma proporção em torno de 7:3 entre parseUrl e parseURL e uma proporção de 6:4 entre userId e userID. O estilo tratar-como-palavra está vencendo no JavaScript. C# permanece fortemente no estilo Microsoft — parseURL domina nos arquivos C#. Python está genuinamente dividido.
Regra de decisão: (a) siga a biblioteca padrão da linguagem em que você está escrevendo; (b) quando a biblioteca padrão for inconsistente, escolha tratar-como-palavra para projetos novos porque faz round-trip; (c) registre a escolha no seu linter ou config de estilo e nunca misture as duas dentro de um mesmo projeto. O tokenizador do Conversor de Maiúsculas e Minúsculas segue a convenção tratar-como-palavra para combinar com lodash e o pacote change-case — cole XMLHttpRequest e você verá xmlHttpRequest, xml_http_request, xml-http-request como saídas camelCase, snake_case e kebab-case.
Slugs de URL: por que kebab-case ganha de snake_case
A documentação oficial do Google Search Central sobre estrutura de URL dá uma recomendação específica de case: use hifens para separar palavras em URLs, não use underscores. O motivo é tokenização. O índice de busca do Google divide URLs em hifens, mas não em underscores. https://example.com/buy-running-shoes é tokenizado como buy, running, shoes — três termos indexáveis que podem corresponder a qualquer uma dessas palavras da query. https://example.com/buy_running_shoes é tokenizado como o único termo buy_running_shoes, que só corresponde a essa string exata.
O efeito prático no ranking é pequeno para páginas já estabelecidas (o Google tem outros sinais) mas real para páginas novas que competem em uma SERP apertada. Em página com pontuação empatada, a URL em kebab-case fica acima.
Há uma segunda razão: sensibilidade a maiúsculas. Paths de URL são sensíveis a maiúsculas/minúsculas em servidores Linux (ou seja, a maior parte da web). /User-Profile e /user-profile viram duas URLs distintas, com entradas de cache separadas e linhas de analytics separadas. kebab-case em minúsculas é a única grafia que não convida o clássico bug “mas funciona no meu Mac”.
Uma receita de quatro passos para o slug, que serve para qualquer título:
- Coloque tudo em minúsculas.
- Substitua sequências de espaço em branco e pontuação por um único hífen.
- Remova hifens no início e no fim.
- Opcionalmente derrube as stopwords (
a,an,the,of,for) para URLs mais curtas — só faça isso se o seu CMS guardar o título original para o cabeçalho da página.
Exemplo trabalhado: "10 Tips for Faster JavaScript: A Complete Guide" → 10-tips-faster-javascript-complete-guide. Os dois-pontos e as stopwords (for, a) caem; o resultado tem 39 caracteres, confortavelmente abaixo da zona ideal de 50-60 caracteres para exibição na SERP. Para mais sobre comprimento de URL e como ele dialoga com limites de caracteres por plataforma, veja o Guia de limites de caracteres e palavras.
O Conversor de Maiúsculas e Minúsculas entrega a saída em kebab-case para qualquer título em uma única colagem — útil quando você está gerando slugs em massa para uma migração de CMS ou um sitemap.
Seis armadilhas de conversão
Converter automaticamente entre cases parece trivial. Não é. Aqui estão os seis lugares onde a coisa quebra.
1. Fronteiras entre número e letra
O que é file2x depois de uma conversão para snake_case? A convenção mainstream — lodash, change-case, PEP 8, o Conversor de Maiúsculas e Minúsculas — trata cada transição letra↔dígito como uma fronteira de token, então file2x vira file / 2 / x e em snake_case fica file_2_x. parseUTF8 vira parse / utf / 8 e parse_utf_8.
Algumas bibliotecas mais antigas (e alguns snippets de re.sub escritos à mão que circulam no Stack Overflow) pulam essa regra e produzem file2x → file2x ou parseutf8. A divergência só aparece quando você migra código entre bibliotecas, e o sintoma é “metade dos meus identificadores foi renomeada e a outra metade não”. Escolha um tokenizador, confirme que ele segue a regra da fronteira de dígito e fique com ele.
2. Letras maiúsculas consecutivas
A regex de fronteira de acrônimo é /([A-Z]+)([A-Z][a-z])/ — separe entre uma sequência de maiúsculas e a maiúscula final que inicia uma nova palavra. XMLHttpRequest casa como XML + HttpRequest, depois Http + Request, gerando os tokens XML / Http / Request.
A volta é o que machuca: XML / Http / Request re-PascalCase vira XmlHttpRequest, não XMLHttpRequest. O acrônimo perdeu a capitalização toda e virou title-case. Esse é o comportamento padrão porque a alternativa — tentar lembrar quais tokens originalmente eram acrônimos — exigiria metadados fora da banda que tokenizadores não têm. Se sua codebase usa o estilo XMLHttpRequest e você roda um rename geral via conversor tratar-como-palavra, vai reescrever silenciosamente todo acrônimo. Teste em uma branch antes, ou use um tokenizador que permita marcar acrônimos explicitamente.
3. Mapeamento de case sensível a Unicode e locale
'I'.toLowerCase() em JavaScript normalmente retorna 'i'. Faça a mesma chamada com o locale turco ativo e ela retorna 'ı' (i sem ponto, U+0131), porque o turco tem duas letras i distintas e a versão minúscula do I maiúsculo é a sem ponto. Esse bug isolado já apareceu em vários rollouts de internacionalização — formulários de login que colocam o usuário em maiúsculas para comparação bloqueiam qualquer usuário turco chamado İrem.
Mais duas minas: o ß.toUpperCase() alemão retorna 'SS' — um caractere vira dois, e código que assume que a conversão de case preserva o tamanho da string está errado. O grego Σ.toLowerCase() é sensível ao contexto: σ no meio da palavra, ς no fim.
Solução: use toLocaleLowerCase() e toLocaleUpperCase() com um locale explícito, ou — se você não souber o locale do usuário — passe 'en-US' para obter o comportamento compatível com ASCII. O Conversor de Maiúsculas e Minúsculas usa os métodos Intl-aware, então essas três entradas são tratadas corretamente. Para o lado regex disso, a Folha de referência Regex cobre a classe Unicode \p{L} de letras.
4. Poluição por smart quotes
Cole uma string vinda do Microsoft Word, Google Docs ou macOS Notes em um conversor de case e você pode carregar passageiros invisíveis: U+2018 / U+2019 / U+201C / U+201D (aspas curvas), U+2014 (travessão), U+00A0 (espaço inquebrável), U+200B (espaço de largura zero). Esses caracteres parecem idênticos aos equivalentes ASCII na maioria das fontes, mas codificam de forma diferente. Um identificador camelCase que contenha um U+00A0 compila em algumas linguagens e em outras não, e o seu grep pelo nome da variável pula a ocorrência sem aviso.
Defesa: normalize a entrada antes de tokenizar. Uma linha — input.normalize('NFKC').replace(/[“”‘’]/g, '"') — limpa a maior parte dos infratores. Ou use a abordagem do Guia do comparador de texto — diff a string suspeita contra sua gêmea ASCII visual e localize os invisíveis na visualização hexadecimal.
5. URLs não devem ser snake_case’d
https://example.com/api/users jogado num conversor para snake_case produz https_example_com_api_users. Tecnicamente é um identificador snake_case válido; semanticamente é um desastre. URLs já estão no case canônico delas (path/case com segmentos de path em kebab-case minúsculo), e tratar a URL inteira como um único identificador apaga a informação estrutural.
A solução é parsear a URL, extrair os segmentos de path e converter cada segmento de forma independente, se você precisar. O Conversor de Maiúsculas e Minúsculas deliberadamente não faz parse automático de URLs porque adivinhar a intenção do usuário é mais perigoso do que ser literal — cole uma URL, receba uma conversão literal; se quiser comportamento segmento por segmento, faça você mesmo.
6. dot.case versus acesso a propriedade
A string user.profile.image é duas coisas diferentes dependendo do contexto. Como identificador dot.case em um arquivo TOML, é um nome único com três segmentos. Como expressão JavaScript, é a propriedade image da propriedade profile de user.
Se você copiar uma string dot.case de um arquivo de configuração e colar no console do JavaScript, o runtime vai tentar avaliar como uma cadeia de propriedades e ou vai dar erro ou vai devolver algo surpreendente. Por outro lado, código que faz manipulação de strings em paths de propriedade JS ('a.b.c'.split('.')) às vezes acaba lidando com identificadores dot.case vindos de outro lugar e tratando-os como paths mais profundos do que deveriam ser. Os dois precisam ficar em namespaces separados.
Convenção: strings dot.case ficam dentro de dados (arquivos de configuração, paths MongoDB, chaves de log); código com identificador único usa camelCase ou snake_case; se você precisa de algo hierárquico no código, use objetos aninhados e a sintaxe de propriedade-ponto da linguagem hospedeira.
Receitas de migração entre linguagens
camelCase JS para snake_case Python
O fluxo mais rápido: copie o identificador JS, cole em um conversor, copie a saída snake_case. Para conversão em massa no nível de código:
import { snakeCase } from 'change-case';
snakeCase('parseHTML'); // 'parse_html'
snakeCase('XMLHttpRequest'); // 'xml_http_request'
snakeCase('parseUTF8'); // 'parse_utf_8'
snakeCase('iPhone'); // 'i_phone'
O último é a pegadinha — iPhone é uma marca em que a fronteira camelCase engana. Para nomes de marca e um punhado de identificadores históricos, faça edição manual depois da conversão.
snake_case SQL para respostas de API em JS/Java
A maioria dos ORMs cuida disso automaticamente. Sequelize tem underscored: true, TypeORM tem a classe SnakeNamingStrategy, Hibernate tem ImplicitNamingStrategyComponentPathImpl. O mapeamento padrão é user_profile_id ↔ userProfileId.
O que quebra: colunas que carregam acrônimos. Uma coluna chamada http_status_code faz round-trip limpo para httpStatusCode, mas se sua codebase prefere HTTPStatusCode, o ORM briga com você. Ou renomeie a coluna para httpstatuscode_code (feio), configure o ORM para preservar acrônimos (raro), ou aceite a convenção padrão.
Componentes React PascalCase para classes CSS kebab-case
// UserProfileCard.tsx
export function UserProfileCard({ user }) {
return <div className="user-profile-card">{user.name}</div>;
}
/* UserProfileCard.module.css */
.user-profile-card { padding: 1rem; }
.user-profile-card__avatar { border-radius: 50%; }
.user-profile-card--featured { background: gold; }
BEM (Block Element Modifier) é a convenção de classe CSS mais comum em par com React: o bloco é o nome do componente em kebab-case, o elemento é block__element, o modificador é block--modifier. No nível de arquivo: UserProfileCard.tsx para o componente, UserProfileCard.module.css para os estilos com escopo — ambos PascalCase, espelhando o nome do componente.
Variáveis de ambiente para configuração da aplicação
# .env (CONSTANT_CASE)
DATABASE_URL=postgres://localhost/myapp
MAX_RETRIES=3
LOG_LEVEL=info
// Node.js
const dbUrl = process.env.DATABASE_URL;
const maxRetries = parseInt(process.env.MAX_RETRIES, 10);
# Python
import os
db_url = os.environ['DATABASE_URL']
max_retries = int(os.environ['MAX_RETRIES'])
O nome da env var permanece em CONSTANT_CASE; o identificador do lado da aplicação segue a convenção de variável da linguagem. Chaves de config YAML/TOML são convencionalmente snake_case (database_url, max_retries) mesmo quando mapeiam para as mesmas envs CONSTANT_CASE em tempo de execução — frameworks como Spring, dotenv e Pydantic fazem o mapeamento de case por você.
Comparativo de bibliotecas e ferramentas
| Ferramenta | Linguagens | Cases suportados | Comportamento do tokenizador |
|---|---|---|---|
lodash (_.camelCase, etc.) | JavaScript | 4 principais + startCase | Tratar-acrônimo-como-palavra |
pacote npm change-case | JavaScript/TS | Todos os 8 cases de código | Tratar-acrônimo-como-palavra |
inflection (Python) | Python | camelCase / snake_case | Tratar-acrônimo-como-palavra |
crate convert_case | Rust | 12+ cases | Acrônimos configuráveis |
strings Go + regex | Go | Implementação manual | Definido pelo projeto |
| VS Code (nativo) | Editor | Apenas UPPER / lower / Title | Só whitespace |
| Extensão “change-case” VS Code | Editor | Todos os 8 cases de código | Tratar-acrônimo-como-palavra |
| Conversor de Maiúsculas e Minúsculas | Navegador | 15 cases (7 texto + 8 código) | Tratar-acrônimo-como-palavra |
Para o dia a dia do código, instale change-case (JS) ou convert_case (Rust). Para Python, o pacote inflection é a escolha canônica, mas uma pequena regex feita à mão cobre 90% dos casos. Para conversões pontuais durante uma revisão de código ou refactor, o Conversor de Maiúsculas e Minúsculas mostra todas as 15 saídas em uma única colagem, então você compara num relance. Se você também precisar contar tokens ou validar o tamanho do identificador, o Contador de Palavras cuida desse lado; para verificar uma regex de tokenizador, use o Testador Regex com os padrões da folha de referência linkada acima.
FAQ
Qual a diferença entre camelCase e PascalCase?
camelCase começa com letra minúscula (userProfile); PascalCase começa com letra maiúscula (UserProfile). Os dois colocam em maiúscula a inicial de cada palavra seguinte, sem separador. camelCase é a convenção para variáveis e funções na maioria das linguagens da família C; PascalCase é a convenção para classes, tipos e componentes React.
Por que Python usa snake_case mas JavaScript usa camelCase?
Python (1991) herdou snake_case de C e da linguagem ABC, depois a PEP 8 codificou como padrão da comunidade. JavaScript (1995) copiou o estilo camelCase do Java, e o Java tinha herdado camelCase do Smalltalk. Os dois são dependências históricas de caminho. Nenhuma das convenções é tecnicamente melhor — estudos de legibilidade dão empate técnico — e consistência dentro de um ecossistema pesa mais do que a escolha em si.
Devo usar parseUrl ou parseURL para acrônimos em camelCase?
parseUrl (tratar-acrônimo-como-palavra) é o padrão moderno — adotado por Google, Apple, lodash e o pacote npm change-case. parseURL (preservar-capitais-do-acrônimo) é o estilo Microsoft .NET e domina em código C#. Para um projeto novo em JavaScript, TypeScript ou Swift, escolha parseUrl porque ele faz round-trip limpo através de conversões snake_case e kebab-case. Independente do que escolher, codifique no seu linter.
kebab-case é melhor do que snake_case para URLs?
Sim. A orientação oficial do Google Search Central é usar hifens, não underscores, em URLs. Os indexadores de busca tokenizam em hifens, mas não em underscores: /user-profile é indexado como user + profile, enquanto /user_profile vira o termo único user_profile. O impacto de ranking por página é pequeno, mas real, e URLs kebab-case em minúsculas também evitam bugs de sensibilidade a maiúsculas/minúsculas em servidores Linux.
Que case usar para nomes de coluna de banco de dados?
snake_case. Os ORMs relevantes (SQLAlchemy, Hibernate, Sequelize, TypeORM, Active Record) usam snake_case por padrão, e os dialetos SQL principais lidam com isso de forma idêntica. PostgreSQL converte identificadores não citados para minúsculas, MySQL é sensível a maiúsculas no Linux e insensível no macOS/Windows, e SQLite trata nomes como strings opacas. snake_case em minúsculas é a única grafia que se comporta igual em qualquer ambiente.
Posso misturar convenções de nomenclatura em um projeto?
Sim — e em geral você precisa. Um app web típico costuma usar camelCase para variáveis JS, snake_case para o banco, kebab-case para classes CSS e URLs, e CONSTANT_CASE para envs. A regra é “uma convenção por camada, nunca misturar dentro da mesma camada”. Codifique a escolha de cada camada no seu linter ou guia de estilo para que revisões de PR parem de gastar tempo com isso.
Como converter entre cases programaticamente?
Para JavaScript e TypeScript, instale change-case ou use _.camelCase / _.snakeCase / _.kebabCase do lodash. Para Python, o pacote inflection ou uma regex curta (re.sub(r'(?<!^)(?=[A-Z])', '_', s).lower() para PascalCase a snake_case). Para Rust, a crate convert_case. Para conversões interativas pontuais, o Conversor de Maiúsculas e Minúsculas mostra as 15 saídas de case para qualquer entrada em uma única página de navegador.
CONSTANT_CASE é só para variáveis de ambiente?
Não, mas envs são o uso mais comum. CONSTANT_CASE serve para qualquer “invariante em runtime”: MAX_RETRIES, API_BASE_URL, DEFAULT_PAGE_SIZE, valores de enum, definições de macro, constantes de configuração no topo do arquivo. A regra é “mudar isto em runtime seria um bug?” — se sim, CONSTANT_CASE; se não, a convenção normal de variável da linguagem. const result = await fetch(url) está perfeitamente bem como está.
Qual a diferença entre dot.case e path/case?
dot.case usa . como separador (user.profile.image) e representa uma chave hierárquica dentro de dados: pacotes Java, paths de campo MongoDB, chaves de configuração TOML, paths de get/set do Lodash. path/case usa / (user/profile/image) e representa uma localização real: paths de URL, paths de filesystem, refs Git. A escolha entre pontos e barras sinaliza “rótulo de dado” versus “localização concreta”.
A folha de decisão de 30 segundos
Três regras que cobrem 95% das perguntas:
-
Para identificadores de código, copie a biblioteca padrão da sua linguagem. Python: snake_case para variáveis e funções, PascalCase para classes. JavaScript e TypeScript: camelCase para variáveis e funções, PascalCase para classes e componentes. Go: primeira letra minúscula para privado ao pacote, primeira letra maiúscula para exportado. Rust: snake_case para variáveis e funções, PascalCase para tipos, SCREAMING_SNAKE para constantes.
-
Para as camadas transversais, o case é fixo independentemente da linguagem. URLs são kebab-case. Classes CSS são kebab-case. Nomes de coluna de banco de dados são snake_case. Variáveis de ambiente são CONSTANT_CASE. Headers HTTP/1.1 são Header-Case (HTTP/2 normaliza para minúsculas na transmissão).
-
Escreva a escolha no seu linter uma vez e pare de discutir. ESLint, Pylint, Clippy, golangci-lint e Rubocop têm regras para isso. Escolha a convenção, configure o linter, e a próxima revisão de PR não gasta uma única palavra com
userIDversususerId.
Quando você realmente precisar converter entre cases — para um refactor, uma migração de CMS, um mapeamento de SQL para API — o Conversor de Maiúsculas e Minúsculas entrega as 15 saídas de case em uma única colagem para você copiar a certa sem tokenizar a entrada na unha. Para trabalho relacionado com texto, veja o Contador de Palavras, o Testador Regex e o Comparador de texto online. Para leituras mais fundas, a Folha de referência Regex cobre os padrões de tokenizador, o Guia do comparador de texto cobre comparações antes/depois durante uma migração, e o Guia de limites de caracteres e palavras cobre orçamentos de comprimento de URL para slugs de SEO.