Skip to content
Volver al blog
Tutoriales

camelCase vs snake_case vs kebab-case: convenciones de nombres 2026

camelCase vs snake_case vs kebab-case en 2026 — 6 estilos de case, matriz de decisión de 7 lenguajes, reglas de acrónimos, SEO de URL y 6 trampas.

14 min de lectura

camelCase vs snake_case vs kebab-case: guía 2026 de convenciones de nombres

¿userID o userId? ¿user_profile o userProfile? ¿URLs con - o con _? Son las pequeñas preguntas que descarrilan las revisiones de PR cinco veces al día. La respuesta no es “preferencia personal”: cada lenguaje principal y cada estándar web tiene una regla establecida, y cuando los ves todos en una sola página deja de haber discusión.

Esta guía cubre los seis cases que vas a encontrarte de verdad en el código (camelCase, PascalCase, snake_case, kebab-case, CONSTANT_CASE, dot.case / path/case / Header-Case), una matriz de decisión para siete lenguajes, el debate parseUrl vs parseURL sobre acrónimos con datos reales de GitHub, los argumentos SEO a favor de URLs en kebab-case y las seis trampas que muerden cuando conviertes automáticamente entre cases. Si quieres ver las 15 salidas de case para cualquier cadena al mismo tiempo, el Convertidor de Mayúsculas y Minúsculas las muestra en vivo dentro de tu navegador.

Los seis cases de un vistazo

Antes de cualquier comparación, aquí tienes la chuleta. Imprímela, pégala en la wiki del equipo o déjala abierta en una pestaña.

Estilo de caseEjemploUso típicoOrigen / popularizador
camelCaseuserProfileImageVariables y métodos en JS, TS, Java, SwiftSmalltalk → Java
PascalCaseUserProfileImageClases, componentes React/Vue, tipos TSLenguaje Pascal
snake_caseuser_profile_imagePython, Ruby, Rust, columnas SQLC / Unix temprano
kebab-caseuser-profile-imageClases CSS, slugs de URL, atributos HTMLLisp / web moderna
CONSTANT_CASEUSER_PROFILE_IMAGEVariables de entorno, constantes globales, macrosMacros de C / entorno Unix
dot.caseuser.profile.imagePaquetes Java, rutas MongoDB, claves TOMLConvención de namespacing
path/caseuser/profile/imageRutas URL, sistema de archivos, refs GitRutas Unix
Header-CaseUser-Profile-ImageNombres de cabeceras HTTP/1.1 (canónicos)RFC 2616

Ocho filas para seis cases “reales”: dot.case, path/case y Header-Case comparten la misma tokenización subyacente con separadores distintos, razón por la cual la mayoría de librerías de case los tratan como una sola familia.

Cada case en profundidad

camelCase: la opción por defecto de JS/Java

camelCase fue idea de Smalltalk, pero Java fue el lenguaje que lo exportó al resto de la industria. Las convenciones de código Java de Sun de 1995 convirtieron a firstName, getUserProfile y xmlParser en la grafía por defecto, y todos los lenguajes que quisieron parecerse a Java —JavaScript, ActionScript, Swift, Kotlin, Dart— heredaron la misma forma.

Regla: la primera palabra en minúsculas, cada palabra siguiente con la inicial mayúscula, sin separadores. Sin guiones bajos, sin guiones, sin espacios. El nombre “camelCase” viene del perfil joroboso que dibujan las letras mayúsculas asomando entre un mar de minúsculas.

Dos casos límite en los que la gente se equivoca: las marcas que empiezan en minúscula (iPhone, eBay, iOS); cuando una de ellas aparece en el código, no fuerces la mayúscula de la i; escríbela como la marca lo hace y acepta el identificador un poco raro. Y los acrónimos, que se tratan en detalle más abajo.

PascalCase: clases y componentes

PascalCase no es más que camelCase con la primera letra en mayúscula. Por eso algunas guías de estilo lo llaman literalmente “UpperCamelCase”. El lenguaje Pascal lo usó en los años setenta y el nombre se quedó.

Dónde vive: nombres de clase en todos los lenguajes OO de la familia C (Java, C#, C++, Kotlin, Swift, TypeScript), nombres de componentes React/Vue/Angular, alias de tipo e interfaces de TypeScript (type UserProfile, interface AuthState) y nombres de módulo/archivo en algunos ecosistemas (UserService.cs en C#).

¿Por qué hace falta un case aparte para las clases? Es puramente una señal visual. Cuando lees new userProfile() frente a new UserProfile(), la segunda forma se lee de inmediato como un tipo y la primera como una llamada a función mal escrita. Los lenguajes que mezclan namespaces de valores y de tipos se apoyan en la capitalización para desambiguar.

snake_case: Python, Ruby, Rust, SQL

snake_case es más antiguo de lo que parece: C y los primeros Unix usaban nombres tipo errno_h y fopen_s porque los teclados de los terminales PDP-11 hacían el guion bajo cómodo y la capitalización estilo Pascal incómoda. Python lo adoptó como convención oficial en PEP 8, la comunidad de Ruby se decantó por él de forma orgánica y Rust lo convirtió en la opción por defecto reforzada por el compilador, con un lint que protesta si tu variable es userId en lugar de user_id.

Regla: todo en minúsculas, palabras unidas por guiones bajos. user_profile_image, parse_html, max_retries.

El ángulo de las bases de datos importa y es la parte que la mayoría de tutoriales por lenguaje se saltan. Casi todos los ORM de SQL —SQLAlchemy, Hibernate, Sequelize, TypeORM, Active Record— usan snake_case por defecto para los nombres de columna, sin importar la convención del lenguaje anfitrión. La razón es la portabilidad: PostgreSQL convierte a minúsculas los identificadores sin comillas, MySQL en Linux distingue mayúsculas, MySQL en macOS/Windows no las distingue, y SQLite trata los nombres de columna como cadenas opacas. snake_case es la única grafía que sobrevive a todos esos escenarios sin necesidad de entrecomillar.

kebab-case: la elección de la web

La web convergió en kebab-case para todo lo que ve el usuario: nombres de clase CSS (.user-profile-image), slugs de URL (/blog/naming-conventions-guide), atributos HTML personalizados (data-user-id), nombres de etiqueta de Web Components (<user-card>, donde la propia especificación exige que contengan un guion).

El propio nombre aparece en unas ocho variantes en la documentación más antigua: “dash-case”, “spinal-case”, “lisp-case”, “skewer-case”, “hyphen-case”. Todas significan lo mismo. “kebab-case” es la que se quedó por una vieja broma de Stack Overflow sobre cómo las palabras parecen carne en un pincho.

Una regla no tan obvia: los nombres de clase HTML y CSS son insensibles a mayúsculas en la práctica, pero la grafía canónica es minúsculas. .User-Profile funciona en la mayoría de navegadores, pero rompe las herramientas del servidor que hashean los nombres de clase y confunde a quienes revisan el código. Quédate en minúsculas.

CONSTANT_CASE: variables de entorno y macros

CONSTANT_CASE (a veces llamado SCREAMING_SNAKE_CASE en los círculos de Rust) es la señal universal de “este valor nunca cambia en tiempo de ejecución”. MAX_RETRIES, API_KEY, DEFAULT_TIMEOUT_MS. Cada lenguaje tiene una convención para esto, y todo sistema de CI, runtime de contenedores y shell espera las variables de entorno en este case (DATABASE_URL, NODE_ENV, PATH).

Trampa: la palabra clave const de JavaScript no significa “usa CONSTANT_CASE”. const result = await fetch(url) es camelCase perfectamente correcto. Reserva CONSTANT_CASE para constantes semánticas de verdad, valores que en C estarían en un #define, esa clase de identificadores donde cambiar el valor en tiempo de ejecución sería un bug. MAX_RETRIES = 3 cumple. result no.

dot.case, path/case, Header-Case

Tres hermanos que comparten el mismo tokenizador con separadores distintos.

dot.case representa claves jerárquicas: paquetes Java (com.example.service), rutas de campo en MongoDB (user.profile.image), claves de configuración TOML/INI ([database.primary]), rutas de métodos de Lodash (_.get(obj, 'user.profile.image')). Al leer una cadena en dot.case, deberías leer “espacio de nombres, espacio de nombres, hoja”.

path/case representa ubicaciones literales: rutas URL, rutas del sistema de archivos, refs de Git (feature/add-auth). La elección entre puntos y barras es significativa: las barras señalan “esto es algo que existe en algún sitio”, los puntos señalan “esto es una etiqueta”.

Header-Case es la convención de HTTP/1.1: Content-Type, Access-Control-Allow-Origin, X-Forwarded-For. Las cabeceras HTTP/1.1 son técnicamente insensibles a mayúsculas (RFC 2616), así que content-type funciona, pero todo framework, toda documentación y todo desarrollador esperan la grafía Header-Case. HTTP/2 y HTTP/3 cambiaron esto: el RFC 7540 §8.1.2 obliga a usar nombres de cabecera en minúsculas sobre el cable para simplificar la compresión de cabeceras (HPACK). En la práctica esto es invisible para el código de aplicación porque todo cliente y servidor HTTP/2 normaliza por ti, pero si alguna vez inspeccionas un frame HTTP/2 en crudo, las cabeceras estarán en kebab-case totalmente en minúsculas.

Matriz de decisión para siete lenguajes

La forma más rápida de zanjar una discusión de nombres es mirar lo que hace la biblioteca estándar del lenguaje. Aquí tienes la matriz.

LenguajeVariableFunciónClaseConstanteNombre de archivoColumna DB
Python (PEP 8)snake_casesnake_casePascalCaseCONSTANT_CASEsnake_case.pysnake_case
JavaScript/TScamelCasecamelCasePascalCaseCONSTANT_CASEkebab-case.jssnake_case
GocamelCase*PascalCase**PascalCasemixedCase***snake_case.gosnake_case
Rustsnake_casesnake_casePascalCaseSCREAMING_SNAKEsnake_case.rssnake_case
JavacamelCasecamelCasePascalCaseCONSTANT_CASEPascalCase.javasnake_case
C#camelCase†PascalCasePascalCasePascalCasePascalCase.cssnake_case
SQLn/asnake_casen/an/an/asnake_case
  • * Go: una primera letra minúscula significa no exportado (privado al paquete); una primera letra mayúscula significa exportado (público). El compilador lo impone.
  • ** Go: las funciones exportadas usan PascalCase (http.NewRequest); las funciones privadas al paquete usan camelCase (http.parseHeader).
  • *** Go: las constantes siguen la misma regla de capitalización exportada/no exportada: MaxRetries para exportadas, maxRetries para privadas. Go evita deliberadamente CONSTANT_CASE.
  • C#: las variables locales y los campos privados son camelCase (algunos códigos prefijan los campos con _: _userName); las propiedades públicas, los métodos y los tipos son PascalCase.

Tres capas que atraviesan todos los lenguajes:

HTML y CSS: los nombres de clase e ID son kebab-case (<div class="user-profile-card">). Los atributos HTML personalizados son kebab-case con prefijo data- (data-user-id). Las propiedades CSS inline son kebab-case (background-color); sus equivalentes en el DOM de JS son camelCase (element.style.backgroundColor).

HTTP: los nombres de cabecera salientes son Header-Case para HTTP/1.1 ('Content-Type': 'application/json') y kebab-case en minúsculas sobre el cable HTTP/2. La mayoría de librerías fetch aceptan cualquiera de las dos grafías y normalizan internamente.

Variables de entorno: CONSTANT_CASE en todas partes: Node, Python, Go, Rust, Bash, Docker, Kubernetes. La convención del archivo .env es la misma: DATABASE_URL=postgres://....

Manejo de acrónimos: Google vs Microsoft

Esta es la pregunta de nombres más polémica en una revisión de código. ¿Debería ser parseUrl o parseURL? ¿userId o userID? ¿HtmlParser o HTMLParser? ¿XmlHttpRequest o XMLHttpRequest?

Existen dos escuelas, y ambas tienen autoridad real detrás.

Tratar el acrónimo como palabra (Google, Apple, JS moderno): parseUrl, userId, HtmlParser. El Google JavaScript Style Guide §5.3 lo recomienda explícitamente. Las Apple Swift API Design Guidelines hacen lo mismo. Los paquetes lodash y change-case producen esta salida por defecto. El argumento es la estabilidad del round-trip: parseUrl tokeniza limpiamente como parse / url, se convierte a parse_url y vuelve a parseUrl sin pérdida de información. parseURL tokeniza como parse / URL, se convierte a parse_u_r_l con un tokenizador ingenuo o a parse_url con uno consciente de acrónimos, pero entonces parse_url no puede decidir si volver a parseUrl o a parseURL, porque la grafía en minúsculas ha perdido la señal del acrónimo.

Preservar la capitalización del acrónimo (Microsoft, .NET, Java antiguo): parseURL, userID, HTMLParser, XMLHttpRequest. Las Microsoft .NET Naming Guidelines limitan esto a acrónimos de 2-3 letras (IO, URL, XML) y usan el estilo de tratar-como-palabra para los más largos (Html sería preserve-caps en una lectura estricta, pero Microsoft escribe HtmlAgilityPack en la práctica). La Win32 API, la BCL de .NET y la mayor parte del código Java anterior a 2010 van por esta vía. Se lee de forma más natural en inglés —parseURL parece “parse U-R-L”— a costa de la propiedad de round-trip.

PEP 8 de Python recomienda nominalmente tratar-como-palabra, pero la biblioteca estándar de Python ha sido históricamente inconsistente: http.server.HTTPServer y xml.etree.ElementTree preservan los acrónimos, y json.JSONDecoder hace lo mismo. Las adiciones más recientes (pathlib.PurePath, dataclasses) tienden a tratar-como-palabra. La línea de PEP 8 es: sigue lo que hace el código a tu alrededor.

Una verificación rápida en el corpus público de GitHub a principios de 2026 (la muestra bigquery-public-data.github_repos de BigQuery, filtrada a archivos TypeScript y JavaScript de repos con más de 1k estrellas) muestra una proporción aproximada de 7:3 entre parseUrl y parseURL y de 6:4 entre userId y userID. El estilo tratar-como-palabra está ganando en JavaScript. C# se mantiene firmemente en el estilo Microsoft: parseURL domina en los archivos C#. Python está genuinamente dividido.

Regla de decisión: (a) sigue la biblioteca estándar del lenguaje en el que escribes; (b) cuando la biblioteca estándar sea inconsistente, elige tratar-como-palabra para proyectos nuevos porque hace round-trip; (c) escribe la elección en tu linter o configuración de estilo y nunca mezcles los dos estilos dentro de un mismo proyecto. El tokenizador del Convertidor de Mayúsculas y Minúsculas sigue la convención de tratar-como-palabra para alinearse con lodash y el paquete change-case: pega XMLHttpRequest y verás xmlHttpRequest, xml_http_request, xml-http-request como salidas camelCase, snake_case y kebab-case.

Slugs de URL: por qué kebab-case le gana a snake_case

Cuando lees la documentación oficial de Google Search Central sobre la estructura de URL, da exactamente una recomendación concreta de case: usa guiones para separar palabras en URLs, no uses guiones bajos. La razón es la tokenización. El índice de búsqueda de Google divide las URLs por guiones pero no por guiones bajos. https://example.com/buy-running-shoes se tokeniza como buy, running, shoes: tres términos indexables que pueden coincidir con cualquiera de esas palabras de la consulta. https://example.com/buy_running_shoes se tokeniza como el término único buy_running_shoes, que solo coincide con esa cadena exacta.

El efecto práctico sobre el ranking es pequeño para páginas establecidas (Google tiene otras señales) pero real para páginas nuevas que compiten en una SERP ajustada. A igualdad de página, la URL en kebab-case ranquea más alto.

Hay una segunda razón: la sensibilidad a mayúsculas. Las rutas URL distinguen mayúsculas en servidores Linux (que son la mayor parte de la web). /User-Profile y /user-profile son dos URLs distintas, dos entradas de caché distintas, dos filas de analítica distintas. kebab-case en minúsculas es la única grafía que no invita al bug “pero funciona en mi Mac”.

Una receta de cuatro pasos para generar slugs que funciona con cualquier título:

  1. Pasar todo a minúsculas.
  2. Reemplazar las secuencias de espacios y puntuación por un solo guion.
  3. Eliminar los guiones iniciales y finales.
  4. Opcionalmente, descartar las stop words (a, an, the, of, for) para acortar las URLs; haz esto solo si tu CMS conserva el título original para el encabezado de la página.

Ejemplo trabajado: "10 Tips for Faster JavaScript: A Complete Guide"10-tips-faster-javascript-complete-guide. Los dos puntos y las stop words (for, a) se eliminan; el resultado tiene 39 caracteres, claramente dentro del rango óptimo de 50-60 caracteres para mostrarse en la SERP. Para más sobre la longitud de URL y cómo interactúa con los límites de caracteres de cada plataforma, consulta la Guía de límites de caracteres y palabras.

El Convertidor de Mayúsculas y Minúsculas te da la salida kebab-case de cualquier título en un solo pegado: útil cuando generas slugs en bulk para migrar un CMS o un sitemap.

Seis trampas de conversión

Convertir automáticamente entre cases parece trivial. No lo es. Aquí están los seis lugares donde se rompe.

1. Bordes entre números y letras

¿Qué es file2x después de una conversión a snake_case? La convención mayoritaria —lodash, change-case, PEP 8, el Convertidor de Mayúsculas y Minúsculas— trata cada transición letra↔dígito como borde de token, así que file2x se convierte en file / 2 / x y a snake_case queda file_2_x. parseUTF8 se convierte en parse / utf / 8 y parse_utf_8.

Algunas librerías más antiguas (y algunos fragmentos re.sub escritos a mano que vas a encontrar en Stack Overflow) se saltan esta regla y producen file2xfile2x o parseutf8. El desajuste solo aparece cuando migras código entre librerías, y el síntoma es “la mitad de mis identificadores fueron renombrados y la otra mitad no”. Elige un tokenizador, verifica que cumpla la regla del borde por dígito y manténlo.

2. Letras mayúsculas consecutivas

La regex del borde por acrónimo es /([A-Z]+)([A-Z][a-z])/: dividir entre una secuencia de mayúsculas y una mayúscula final que arranca palabra nueva. XMLHttpRequest coincide como XML + HttpRequest, luego Http + Request, generando los tokens XML / Http / Request.

El viaje de vuelta es donde muerde: XML / Http / Request re-PascalizadoCase queda como XmlHttpRequest, no XMLHttpRequest. El acrónimo se ha convertido a Title Case. Este es el comportamiento estándar porque la alternativa —intentar recordar qué tokens eran originalmente acrónimos— requiere metadatos fuera de banda que los tokenizadores no tienen. Si tu base de código usa el estilo XMLHttpRequest y lanzas un renombrado a nivel de proyecto con un convertidor de tratar-como-palabra, vas a reescribir silenciosamente cada acrónimo. Pruébalo primero en una rama o usa un tokenizador que te deje marcar acrónimos explícitamente.

3. Conversión de case sensible a Unicode y locale

'I'.toLowerCase() en JavaScript normalmente devuelve 'i'. Ejecuta la misma llamada con el locale turco activo y devuelve 'ı' (i sin punto, U+0131), porque el turco tiene dos letras i distintas y la minúscula de la I mayúscula es la sin punto. Este bug se ha colado en muchos despliegues de internacionalización: formularios de login que pasan el nombre de usuario a mayúsculas para comparar bloquean silenciosamente a cada usuario turco llamado İrem.

Dos minas adicionales: el alemán ß.toUpperCase() devuelve 'SS', un carácter se convierte en dos, y cualquier código que asuma que la conversión de case preserva la longitud de la cadena está equivocado. El griego Σ.toLowerCase() es sensible al contexto: σ a mitad de palabra, ς al final de palabra.

Solución: usa toLocaleLowerCase() y toLocaleUpperCase() con un locale explícito, o, si no conoces el locale del usuario, pasa 'en-US' para obtener el comportamiento compatible con ASCII. El Convertidor de Mayúsculas y Minúsculas usa los métodos conscientes de Intl para que esas tres entradas se manejen correctamente. Para el lado regex de esto, la Hoja de referencia de Regex cubre la clase Unicode \p{L} para letras.

4. Contaminación por comillas tipográficas

Pega una cadena desde Microsoft Word, Google Docs o macOS Notas en un convertidor de case y puede que arrastres pasajeros invisibles: U+2018 / U+2019 / U+201C / U+201D (comillas tipográficas), U+2014 (raya larga), U+00A0 (espacio no separable), U+200B (espacio de ancho cero). Las cuatro se ven idénticas a sus equivalentes ASCII en la mayoría de fuentes pero se codifican de forma distinta. Un identificador camelCase que contenga un U+00A0 compilará en algunos lenguajes y en otros no, y tu grep por el nombre de la variable se saltará silenciosamente la ocurrencia.

Defensa: normaliza la entrada antes de tokenizar. Una línea como input.normalize('NFKC').replace(/[“”‘’]/g, '"') quita la mayoría de los intrusos. O usa el enfoque de la Guía del comparador de texto: compara la cadena sospechosa contra su gemela ASCII visual y detecta los invisibles en una vista hexadecimal.

5. Las URLs no deberían pasarse a snake_case

https://example.com/api/users pegada en un convertidor a snake_case produce https_example_com_api_users. Técnicamente un identificador snake_case válido; semánticamente un desastre. Las URLs ya están en su case canónico (path/case con segmentos en kebab-case en minúsculas), y tratar la URL completa como un solo identificador pierde la información estructural.

La solución es parsear la URL, extraer los segmentos del path y convertir cada segmento de forma independiente si realmente lo necesitas. El Convertidor de Mayúsculas y Minúsculas deliberadamente no parsea las URLs en automático porque adivinar la intención del usuario es más peligroso que ser literal: pega una URL, obtén una conversión literal; si querías comportamiento segmento a segmento, hazlo tú.

6. dot.case frente a acceso a propiedades

La cadena user.profile.image son dos cosas distintas según el contexto. Como identificador dot.case en un archivo TOML, es un nombre con tres segmentos. Como expresión JavaScript, es la propiedad image de la propiedad profile del objeto user.

Si copias una cadena dot.case fuera de un archivo de configuración y la pegas en una consola JavaScript, el runtime intentará evaluarla como una cadena de propiedades y devolverá un error o algo sorprendente. A la inversa, código que manipula rutas de propiedad JS por string ('a.b.c'.split('.')) a veces termina recibiendo identificadores dot.case de otra parte y tratándolos como rutas más profundas de lo que se pretendía. Ambos deben mantenerse en namespaces separados.

Convención: las cadenas dot.case se quedan dentro de los datos (archivos de configuración, rutas de MongoDB, claves de log); el código de identificador único usa camelCase o snake_case; si necesitas algo jerárquico en código, usa objetos anidados y la sintaxis dot-property del lenguaje anfitrión.

Recetas de migración entre lenguajes

De camelCase de JS a snake_case de Python

El flujo más rápido: copia el identificador JS, pégalo en un convertidor, copia la salida snake_case. Para una conversión a nivel de código en bulk:

import { snakeCase } from 'change-case';

snakeCase('parseHTML');         // 'parse_html'
snakeCase('XMLHttpRequest');    // 'xml_http_request'
snakeCase('parseUTF8');         // 'parse_utf_8'
snakeCase('iPhone');            // 'i_phone'

El último es el truco: iPhone es un nombre de marca donde el borde camelCase engaña. Para nombres de marca y un puñado de identificadores históricos, edita a mano después de la conversión.

De snake_case de SQL a respuestas de API en JS/Java

La mayoría de ORM hacen esto por ti automáticamente. Sequelize tiene underscored: true, TypeORM tiene la clase SnakeNamingStrategy, Hibernate tiene ImplicitNamingStrategyComponentPathImpl. El mapeo por defecto es user_profile_iduserProfileId.

Lo que se rompe: columnas con acrónimos. Una columna llamada http_status_code hace round-trip a httpStatusCode limpiamente, pero si tu código prefiere HTTPStatusCode, el ORM se va a pelear contigo. O renombras la columna a httpstatuscode_code (feo), o configuras el ORM para preservar los acrónimos (raro), o aceptas la convención estándar.

De componentes React en PascalCase a clases CSS en 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) es la convención de clases CSS más común que se empareja con React: el bloque es el nombre del componente en kebab-case, el elemento es block__element, el modificador es block--modifier. A nivel de archivo: UserProfileCard.tsx para el componente, UserProfileCard.module.css para los estilos con scope, ambos PascalCase, coincidiendo con el nombre del componente.

De variables de entorno a configuración de aplicación

# .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'])

El nombre de la variable de entorno se queda en CONSTANT_CASE; el identificador del lado de la aplicación sigue la convención de variables del lenguaje. Las claves de configuración YAML/TOML son convencionalmente snake_case (database_url, max_retries) aunque se mapean a las mismas variables de entorno en CONSTANT_CASE en tiempo de ejecución; frameworks como Spring, dotenv y Pydantic gestionan el mapeo de case por ti.

Comparativa de librerías y herramientas

HerramientaLenguajesCases soportadosComportamiento del tokenizador
lodash (_.camelCase, etc.)JavaScript4 principales + startCaseTrata acrónimo como palabra
Paquete npm change-caseJavaScript/TSLos 8 cases de programaciónTrata acrónimo como palabra
inflection (Python)PythoncamelCase / snake_caseTrata acrónimo como palabra
Crate convert_caseRust12+ casesAcrónimos configurables
Go strings + regexGoHecho a manoDefinido por proyecto
VS Code (integrado)EditorUPPER / lower / Title onlySolo whitespace
Extensión “change-case” en VS CodeEditorLos 8 cases de programaciónTrata acrónimo como palabra
Convertidor de Mayúsculas y MinúsculasNavegador15 cases (7 texto + 8 código)Trata acrónimo como palabra

Para el día a día del código, instala change-case (JS) o convert_case (Rust). Para Python, el paquete inflection es la elección canónica, pero una pequeña regex escrita a mano cubre el 90% de los casos. Para conversiones puntuales durante una revisión o un refactor, el Convertidor de Mayúsculas y Minúsculas muestra las 15 salidas en un solo pegado para que puedas compararlas de un vistazo. Si además necesitas contar tokens o validar la longitud de un identificador, el Contador de Palabras cubre ese lado; para verificar una regex de tokenizador, usa el Probador de Regex con los patrones de la hoja de referencia enlazada arriba.

FAQ

¿Cuál es la diferencia entre camelCase y PascalCase?

camelCase empieza con letra minúscula (userProfile); PascalCase empieza con letra mayúscula (UserProfile). Ambos ponen mayúscula en cada palabra siguiente sin separador. camelCase es la convención para variables y funciones en la mayoría de lenguajes de la familia C; PascalCase es la convención para clases, tipos y componentes React.

¿Por qué Python usa snake_case y JavaScript usa camelCase?

Python (1991) heredó snake_case de C y del lenguaje ABC, y luego PEP 8 lo codificó como estándar de la comunidad. JavaScript (1995) copió el estilo camelCase de Java, y Java había heredado camelCase de Smalltalk. Ambos son dependencias históricas del camino. Ninguna convención es técnicamente mejor: los estudios de legibilidad están aproximadamente empatados, y la consistencia dentro de un ecosistema importa más que la elección en sí.

¿Debería usar parseUrl o parseURL para acrónimos en camelCase?

parseUrl (tratar acrónimo como palabra) es el valor por defecto moderno, usado por Google, Apple, lodash y el paquete npm change-case. parseURL (preservar mayúsculas del acrónimo) es el estilo Microsoft .NET y domina en el código C#. Para un proyecto nuevo en JavaScript, TypeScript o Swift, elige parseUrl porque hace round-trip limpio en conversiones a snake_case y kebab-case. Sea cual sea tu elección, codifícala en tu linter.

¿Es mejor kebab-case que snake_case para URLs?

Sí. La guía oficial de Google Search Central es usar guiones, no guiones bajos, en las URLs. Los indexadores de búsqueda tokenizan por guiones pero no por guiones bajos: /user-profile se indexa como user + profile, mientras que /user_profile se indexa como el único término user_profile. El impacto en ranking es pequeño por página pero real, y las URLs en kebab-case en minúsculas también evitan bugs de sensibilidad a mayúsculas en servidores Linux.

¿Qué case deberían usar los nombres de columna de base de datos?

snake_case. Todo ORM importante (SQLAlchemy, Hibernate, Sequelize, TypeORM, Active Record) lo usa por defecto, y todo dialecto SQL importante lo gestiona de forma idéntica. PostgreSQL convierte a minúsculas los identificadores sin comillas, MySQL es sensible a mayúsculas en Linux e insensible en macOS/Windows, y SQLite trata los nombres como opacos. snake_case en minúsculas es la única grafía que se comporta igual en todos los entornos.

¿Puedo mezclar convenciones de nombres en un mismo proyecto?

Sí, y normalmente tienes que hacerlo. Una aplicación web típica puede usar camelCase para variables JS, snake_case para la base de datos, kebab-case para clases CSS y URLs, y CONSTANT_CASE para variables de entorno. La regla es “una convención por capa, nunca mezclar dentro de una sola capa”. Codifica la elección por capa en tu linter o guía de estilo para que las revisiones de PR dejen de gastar palabras en eso.

¿Cómo convierto entre cases de forma programática?

Para JavaScript y TypeScript, instala change-case o usa _.camelCase / _.snakeCase / _.kebabCase de lodash. Para Python, el paquete inflection o una regex corta (re.sub(r'(?<!^)(?=[A-Z])', '_', s).lower() para pasar de PascalCase a snake_case). Para Rust, el crate convert_case. Para conversiones interactivas puntuales, el Convertidor de Mayúsculas y Minúsculas muestra las 15 salidas de case para cualquier entrada en una sola página del navegador.

¿CONSTANT_CASE es solo para variables de entorno?

No, pero las variables de entorno son el uso más común. CONSTANT_CASE es para cualquier “invariante en tiempo de ejecución”: MAX_RETRIES, API_BASE_URL, DEFAULT_PAGE_SIZE, valores de enum, definiciones de macro, constantes de configuración globales. La regla es “¿sería un bug cambiar esto en tiempo de ejecución?”: si sí, CONSTANT_CASE; si no, la convención normal del lenguaje. const result = await fetch(url) está perfectamente bien tal cual.

¿Cuál es la diferencia entre dot.case y path/case?

dot.case usa . como separador (user.profile.image) y representa una clave jerárquica dentro de los datos: paquetes Java, rutas de campo MongoDB, claves de configuración TOML, rutas get/set de Lodash. path/case usa / (user/profile/image) y representa una ubicación real: rutas URL, rutas del sistema de archivos, refs Git. La elección entre puntos y barras señala “etiqueta de datos” frente a “ubicación real”.

La hoja de decisión de 30 segundos

Tres reglas que cubren el 95% de las preguntas:

  1. Para identificadores de código, copia la biblioteca estándar de tu lenguaje. Python: snake_case para variables y funciones, PascalCase para clases. JavaScript y TypeScript: camelCase para variables y funciones, PascalCase para clases y componentes. Go: primera letra minúscula para privado al paquete, primera letra mayúscula para exportado. Rust: snake_case para variables y funciones, PascalCase para tipos, SCREAMING_SNAKE para constantes.

  2. Para las capas transversales, el case es fijo independientemente del lenguaje. Las URLs son kebab-case. Las clases CSS son kebab-case. Los nombres de columna de base de datos son snake_case. Las variables de entorno son CONSTANT_CASE. Las cabeceras HTTP/1.1 son Header-Case (HTTP/2 normaliza a minúsculas sobre el cable).

  3. Escribe la elección en tu linter una vez y deja de discutir. ESLint, Pylint, Clippy, golangci-lint y Rubocop tienen reglas para esto. Elige la convención, configura el linter y la próxima revisión de PR no gasta ni una palabra en userID frente a userId.

Cuando de verdad necesites convertir entre cases —para un refactor, una migración de CMS, un mapeo SQL-a-API— el Convertidor de Mayúsculas y Minúsculas te da las 15 salidas en un solo pegado para que copies la correcta sin tener que tokenizar la entrada a mano. Para trabajo de texto relacionado, mira el Contador de Palabras, el Probador de Regex y el Comparador de texto en línea. Para lecturas más profundas, la Hoja de referencia de Regex cubre los patrones de tokenizador, la Guía del comparador de texto cubre las comparaciones antes/después durante una migración, y la Guía de límites de caracteres y palabras cubre los presupuestos de longitud de URL para slugs SEO.

Artículos relacionados

Ver todos los artículos