camelCase vs snake_case vs kebab-case : guide 2026 des conventions de nommage
userID ou userId ? user_profile ou userProfile ? Les URL avec - ou _ ? Ce sont les petites questions qui font dérailler une revue de PR cinq fois par jour. La réponse n’est pas une « préférence personnelle » : chaque langage grand public et chaque standard web a une règle établie, et dès que vous les voyez sur une seule page, le bruit tombe à zéro.
Ce guide couvre les six cases que vous croiserez réellement dans le code (camelCase, PascalCase, snake_case, kebab-case, CONSTANT_CASE, dot.case / path/case / Header-Case), une matrice de décision pour sept langages, le débat parseUrl-vs-parseURL sur les acronymes avec de vraies données GitHub, l’argument SEO pour les URL en kebab-case, et les six pièges qui mordent quand vous convertissez automatiquement d’une case à l’autre. Si vous voulez voir les 15 sorties de case pour une chaîne donnée d’un seul coup, le Convertisseur de casse les rend en direct dans votre navigateur.
Les six cases en un coup d’œil
Avant tout travail de comparaison, voici la fiche mémo. Imprimez-la, collez-la dans le wiki de votre équipe, ou gardez-la simplement ouverte dans un onglet.
| Style de case | Exemple | Usage typique | Origine / popularisateur |
|---|---|---|---|
| camelCase | userProfileImage | Variables et méthodes JS, TS, Java, Swift | Smalltalk → Java |
| PascalCase | UserProfileImage | Classes, composants React/Vue, types TS | Langage Pascal |
| snake_case | user_profile_image | Python, Ruby, Rust, colonnes SQL | C / Unix des débuts |
| kebab-case | user-profile-image | Classes CSS, slugs d’URL, attributs HTML | Lisp / web moderne |
| CONSTANT_CASE | USER_PROFILE_IMAGE | Variables d’env, constantes globales, macros | Macros C / env Unix |
| dot.case | user.profile.image | Packages Java, chemins MongoDB, clés TOML | Convention de namespace |
| path/case | user/profile/image | Chemins d’URL, système de fichiers, refs Git | Chemins Unix |
| Header-Case | User-Profile-Image | Noms d’en-têtes HTTP/1.1 (canonique) | RFC 2616 |
Huit lignes pour six cases « réelles » : dot.case, path/case et Header-Case partagent toutes la même tokenisation sous-jacente avec des séparateurs différents, raison pour laquelle la plupart des bibliothèques de case les traitent comme une seule famille.
Chaque case en profondeur
camelCase : le défaut JS/Java
camelCase était l’idée de Smalltalk, mais c’est Java qui l’a exporté vers le reste de l’industrie. Les conventions de code Java de Sun en 1995 ont fait de firstName, getUserProfile et xmlParser l’orthographe par défaut, et tout langage qui voulait avoir l’air « Java-ish » — JavaScript, ActionScript, Swift, Kotlin, Dart — a hérité de la même forme.
Règle : mettre le premier mot en minuscules, capitaliser chaque mot suivant, et supprimer entièrement le séparateur. Pas de tirets bas, pas de traits d’union, pas d’espaces. Le nom « camelCase » vient du contour bosselé que dessinent les majuscules pointant à travers une mer de minuscules — comme les bosses d’un chameau.
Deux cas limites que les gens ratent : les noms de marque qui commencent par une minuscule (iPhone, eBay, iOS). Quand l’un d’eux apparaît dans le code, ne forcez pas la capitalisation du i ; orthographiez-le comme la marque le fait et acceptez l’identifiant légèrement bizarre. Et les acronymes, traités en détail plus bas.
PascalCase : classes et composants
PascalCase, c’est simplement camelCase avec la première lettre en majuscule. Certains guides de style l’appellent d’ailleurs « UpperCamelCase » pour cette raison. Le langage Pascal l’a utilisé dans les années 1970 et le nom est resté.
Où il vit : les noms de classe dans chaque langage OO de la famille C (Java, C#, C++, Kotlin, Swift, TypeScript), les noms de composants React/Vue/Angular, les alias de type et les interfaces TypeScript (type UserProfile, interface AuthState), et les noms de modules/fichiers dans certains écosystèmes (UserService.cs en C#).
Pourquoi une case séparée pour les classes ? C’est purement un signal visuel. Quand vous lisez new userProfile() versus new UserProfile(), le second se lit immédiatement comme un type et le premier comme un appel de fonction qui a mal tourné. Les langages qui mélangent les espaces de noms de valeurs et de types s’appuient sur la capitalisation pour désambiguïser.
snake_case : Python, Ruby, Rust, SQL
snake_case est plus ancien que la plupart des gens ne le pensent. C et Unix des débuts utilisaient des noms du style errno_h et fopen_s parce que les claviers des terminaux PDP-11 rendaient les tirets bas faciles à taper et la capitalisation à la Pascal pénible. Python l’a adopté comme convention officielle PEP 8, la communauté Ruby s’y est installée organiquement, et Rust en a fait le défaut imposé par le compilateur avec un lint qui se plaint si votre variable s’appelle userId au lieu de user_id.
Règle : tout en minuscules, mots reliés par des tirets bas. user_profile_image, parse_html, max_retries.
L’angle base de données compte et c’est la partie que la plupart des tutoriels de langage sautent. Presque chaque ORM SQL (SQLAlchemy, Hibernate, Sequelize, TypeORM, Active Record) prend snake_case par défaut pour les noms de colonnes, quel que soit le langage hôte. La raison est la portabilité : PostgreSQL replie les identifiants non quotés en minuscules, MySQL sur Linux est sensible à la casse, MySQL sur macOS/Windows ne l’est pas, et SQLite traite les noms de colonnes comme des chaînes opaques. snake_case est la seule orthographe qui survit à tout cela sans guillemetage.
kebab-case : le choix du web
Le web a convergé vers kebab-case pour tout ce qui est visible par l’utilisateur : noms de classes CSS (.user-profile-image), slugs d’URL (/blog/naming-conventions-guide), attributs HTML personnalisés (data-user-id), noms de balises Web Component (<user-card>, dont la spec exige justement qu’ils contiennent un trait d’union).
Le nom lui-même apparaît dans à peu près huit variantes dans les anciens docs — « dash-case », « spinal-case », « lisp-case », « skewer-case », « hyphen-case ». Cela veut dire la même chose. « kebab-case » est celui qui est resté à cause d’une vieille blague Stack Overflow sur la ressemblance entre les mots et la viande sur une brochette.
Une règle non évidente : les noms de classe HTML et CSS sont en pratique insensibles à la casse, mais l’orthographe canonique est en minuscules. .User-Profile fonctionne dans la plupart des navigateurs, mais il casse l’outillage côté serveur qui hash les noms de classe, et il déroute les relecteurs de code. Restez en minuscules.
CONSTANT_CASE : variables d’env et macros
CONSTANT_CASE (parfois SCREAMING_SNAKE_CASE dans les cercles Rust) est le signal universel « cette valeur ne change jamais à l’exécution ». MAX_RETRIES, API_KEY, DEFAULT_TIMEOUT_MS. Chaque langage a une convention pour cela, et chaque système CI, runtime de conteneur et shell attend les variables d’environnement dans cette case (DATABASE_URL, NODE_ENV, PATH).
Piège : le mot-clé const de JavaScript ne signifie pas « utiliser CONSTANT_CASE ». const result = await fetch(url) est du camelCase parfaitement correct. Gardez CONSTANT_CASE pour les vraies constantes sémantiques : des valeurs qui seraient #define-es en C, du genre où changer la valeur à l’exécution est un bug. MAX_RETRIES = 3 se qualifie. result non.
dot.case, path/case, Header-Case
Trois frères qui partagent le même tokeniseur avec des séparateurs différents.
dot.case représente des clés hiérarchiques : packages Java (com.example.service), chemins de champs MongoDB (user.profile.image), clés de configuration TOML/INI ([database.primary]), chemins de méthodes Lodash (_.get(obj, 'user.profile.image')). En lisant une chaîne dot.case, vous devriez voir « namespace, namespace, feuille ».
path/case représente des emplacements littéraux : chemins d’URL, chemins du système de fichiers, refs Git (feature/add-auth). Le choix points-versus-slashes a du sens : les slashes signalent « c’est une vraie chose quelque part », les points signalent « c’est une étiquette ».
Header-Case est la convention HTTP/1.1 : Content-Type, Access-Control-Allow-Origin, X-Forwarded-For. Les en-têtes HTTP/1.1 sont techniquement insensibles à la casse (RFC 2616), donc content-type fonctionne, mais chaque framework, chaque documentation et chaque développeur attend l’orthographe Header-Case. HTTP/2 et HTTP/3 ont changé cela : la RFC 7540 §8.1.2 impose des noms d’en-têtes en minuscules sur le fil pour simplifier la compression d’en-têtes (HPACK). En pratique, c’est invisible pour le code applicatif parce que chaque client et serveur HTTP/2 normalise pour vous, mais si vous inspectez un jour une trame HTTP/2 brute, les en-têtes seront en kebab-case minuscule.
Matrice de décision pour sept langages
La façon la plus rapide de régler une dispute de nommage est de regarder ce que fait la bibliothèque standard du langage. Voici la matrice.
| Langage | Variable | Fonction | Classe | Constante | Nom de fichier | Colonne BDD |
|---|---|---|---|---|---|---|
| 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 : une première lettre en minuscule signifie non exporté (privé au package) ; une première lettre en majuscule signifie exporté (public). Le compilateur l’impose.**Go : les fonctions exportées sont en PascalCase (http.NewRequest) ; les fonctions privées au package sont en camelCase (http.parseHeader).***Go : les constantes suivent la même règle de capitalisation exporté/non exporté —MaxRetriespour exporté,maxRetriespour non exporté. Go évite délibérément CONSTANT_CASE.†C# : les variables locales et champs privés sont en camelCase (certaines bases préfixent les champs avec_:_userName) ; les propriétés, méthodes et types publics sont en PascalCase.
Trois couches qui traversent tous les langages :
HTML et CSS : les noms de classes et les ID sont en kebab-case (<div class="user-profile-card">). Les attributs HTML personnalisés sont en kebab-case avec un préfixe data- (data-user-id). Les propriétés CSS inline sont en kebab-case (background-color) ; les équivalents DOM en JS sont en camelCase (element.style.backgroundColor).
HTTP : les noms d’en-têtes sortants sont en Header-Case pour HTTP/1.1 ('Content-Type': 'application/json') et en kebab-case minuscule sur le fil HTTP/2. La plupart des bibliothèques fetch acceptent l’une ou l’autre orthographe et normalisent en interne.
Variables d’environnement : CONSTANT_CASE partout — Node, Python, Go, Rust, Bash, Docker, Kubernetes. La convention du fichier .env est la même : DATABASE_URL=postgres://....
Gestion des acronymes : Google vs Microsoft
C’est la question de nommage la plus controversée en revue de code. Faut-il écrire parseUrl ou parseURL ? userId ou userID ? HtmlParser ou HTMLParser ? XmlHttpRequest ou XMLHttpRequest ?
Deux écoles existent, et chacune a une vraie autorité derrière elle.
Acronyme-traité-comme-un-mot (Google, Apple, JS moderne) : parseUrl, userId, HtmlParser. Le Google JavaScript Style Guide §5.3 le recommande explicitement. Les Apple Swift API Design Guidelines font de même. Les paquets lodash et change-case produisent cette sortie par défaut. L’argument est la stabilité aller-retour : parseUrl se tokenise proprement en parse / url, se convertit en parse_url, et revient à parseUrl sans perte d’information. parseURL se tokenise en parse / URL, se convertit en parse_u_r_l sous un tokeniseur naïf ou parse_url sous un tokeniseur conscient des acronymes ; à ce stade, parse_url ne peut plus décider s’il doit revenir en parseUrl ou parseURL, car l’orthographe tout-en-minuscules a perdu le signal d’acronyme.
Capitalisation d’acronyme préservée (Microsoft, .NET, Java ancien) : parseURL, userID, HTMLParser, XMLHttpRequest. Les Microsoft .NET Naming Guidelines limitent cela aux acronymes de 2-3 lettres (IO, URL, XML) et utilisent le traité-comme-un-mot pour les plus longs (Html serait préservé sous la lecture stricte, mais Microsoft écrit HtmlAgilityPack en pratique). L’API Win32, la BCL .NET et la plupart du code Java pré-2010 vont dans ce sens. Cela se lit plus naturellement pour un anglophone (parseURL ressemble à « parse U-R-L ») au prix de la propriété d’aller-retour.
Le PEP 8 de Python recommande nominalement le traité-comme-un-mot, mais la bibliothèque standard Python est historiquement incohérente : http.server.HTTPServer et xml.etree.ElementTree préservent les acronymes tandis que json.JSONDecoder fait pareil. Les ajouts plus récents (pathlib.PurePath, dataclasses) penchent vers le traité-comme-un-mot. La ligne du PEP 8 est : suivez ce que fait le code environnant.
Un sondage sur le corpus public GitHub début 2026 (l’échantillon BigQuery bigquery-public-data.github_repos, filtré sur les fichiers TypeScript et JavaScript des dépôts avec 1k+ étoiles) montre un ratio d’environ 7:3 de parseUrl versus parseURL et un ratio 6:4 de userId versus userID. Le style traité-comme-un-mot gagne en JavaScript. C# reste fortement Microsoft-style — parseURL domine dans les fichiers C#. Python est vraiment partagé.
Règle de décision : (a) suivez la bibliothèque standard du langage dans lequel vous écrivez ; (b) quand la bibliothèque standard est incohérente, choisissez le traité-comme-un-mot pour les projets greenfield parce qu’il fait l’aller-retour ; (c) écrivez le choix dans votre linter ou config de style et ne mélangez jamais les deux au sein d’un même projet. Le tokeniseur du Convertisseur de casse suit la convention traité-comme-un-mot pour s’aligner sur lodash et le paquet change-case. Collez XMLHttpRequest et vous verrez xmlHttpRequest, xml_http_request, xml-http-request comme sorties camelCase, snake_case et kebab-case.
Slugs d’URL : pourquoi kebab-case bat snake_case
Quand vous lisez la documentation officielle de Google Search Central sur la structure d’URL, elle donne exactement une recommandation de case précise : utiliser des traits d’union pour séparer les mots dans les URL, ne pas utiliser de tirets bas. La raison est la tokenisation. L’index de recherche de Google découpe les URL sur les traits d’union mais pas sur les tirets bas. https://example.com/buy-running-shoes est tokenisé en buy, running, shoes — trois termes indexables qui peuvent matcher chacun de ces mots de requête. https://example.com/buy_running_shoes est tokenisé comme le terme unique buy_running_shoes, qui ne matche que cette chaîne exacte.
L’effet pratique sur le classement est petit pour les pages établies (Google a d’autres signaux) mais réel pour les nouvelles pages en compétition dans une SERP serrée. Sur une page à égalité, l’URL en kebab-case se classe plus haut.
Il y a une seconde raison : la sensibilité à la casse. Les chemins d’URL sont sensibles à la casse sur les serveurs Linux (la majorité du web). /User-Profile et /user-profile sont deux URL différentes, deux entrées de cache différentes, deux lignes d’analytics différentes. Le kebab-case minuscule est la seule orthographe qui n’invite pas un bug du genre « mais ça marche sur mon Mac ».
Une recette de slug en quatre étapes qui fonctionne pour tout titre :
- Tout mettre en minuscules.
- Remplacer les suites d’espaces et de ponctuation par un seul trait d’union.
- Retirer les traits d’union en tête et en queue.
- Optionnellement supprimer les mots vides (
a,an,the,of,for) pour des URL plus courtes — à faire seulement si votre CMS garde le titre original pour le titre de la page.
Exemple travaillé : "10 Tips for Faster JavaScript: A Complete Guide" → 10-tips-faster-javascript-complete-guide. Les deux-points et les mots vides (for, a) sont supprimés ; le résultat fait 39 caractères, bien en-dessous de la zone idéale de 50-60 caractères pour l’affichage SERP. Pour en savoir plus sur la longueur d’URL et son interaction avec les limites de caractères par plateforme, voir le Guide des limites de caractères et de mots.
Le Convertisseur de casse vous donne la sortie kebab-case pour tout titre en un seul collage, utile quand vous générez en masse des slugs pour une migration CMS ou un sitemap.
Six pièges de conversion
Convertir automatiquement entre les cases a l’air trivial. Ça ne l’est pas. Voici les six endroits où ça casse.
1. Frontières chiffre-lettre
Que vaut file2x après une conversion en snake_case ? La convention dominante (lodash, change-case, PEP 8, le Convertisseur de casse) traite chaque transition lettre↔chiffre comme une frontière de token, donc file2x devient file / 2 / x et se snake_case en file_2_x. parseUTF8 devient parse / utf / 8 et parse_utf_8.
Certaines bibliothèques plus anciennes (et certains snippets re.sub écrits à la main que vous trouverez sur Stack Overflow) sautent cette règle et produisent file2x → file2x ou parseutf8. Le décalage n’apparaît que lors d’une migration de code entre bibliothèques, et le symptôme est « la moitié de mes identifiants ont été renommés et l’autre non ». Choisissez un tokeniseur, vérifiez qu’il suit la règle de frontière sur les chiffres, et tenez-vous y.
2. Lettres majuscules consécutives
La regex de frontière d’acronyme est /([A-Z]+)([A-Z][a-z])/ : séparer entre une suite de capitales et une dernière capitale qui commence un nouveau mot. XMLHttpRequest matche en XML + HttpRequest, puis Http + Request, donnant les tokens XML / Http / Request.
Le voyage retour est là où ça mord : XML / Http / Request re-PascalCasé devient XmlHttpRequest, et non XMLHttpRequest. L’acronyme s’est fait title-caser. C’est le comportement standard parce que l’alternative (essayer de se rappeler quels tokens étaient à l’origine des acronymes) exige des métadonnées hors-bande que les tokeniseurs n’ont pas. Si votre base est en style XMLHttpRequest et que vous lancez un renommage projet-wide via un convertisseur traité-comme-un-mot, vous allez silencieusement réécrire chaque acronyme. Testez sur une branche d’abord, ou utilisez un tokeniseur qui vous laisse marquer les acronymes explicitement.
3. Casse Unicode et sensible à la locale
'I'.toLowerCase() en JavaScript renvoie habituellement 'i'. Lancez le même appel avec la locale turque active et il renvoie 'ı' (i sans point, U+0131), parce que le turc a deux lettres i distinctes et que le minuscule du I majuscule est celui sans point. Ce seul bug a été livré dans bien des déploiements d’internationalisation : des formulaires de connexion qui mettent le nom d’utilisateur en majuscules pour comparer bloquent silencieusement chaque utilisateur turc nommé İrem.
Deux autres mines : l’allemand ß.toUpperCase() renvoie 'SS', un caractère devient deux, et tout code qui suppose que la conversion de casse préserve la longueur de chaîne se trompe. Le grec Σ.toLowerCase() est sensible au contexte : σ au milieu d’un mot, ς à la fin.
Solution : utilisez toLocaleLowerCase() et toLocaleUpperCase() avec une locale explicite, ou, si vous ne connaissez pas la locale de l’utilisateur, passez 'en-US' pour obtenir le comportement ASCII-compatible. Le Convertisseur de casse utilise les méthodes Intl-aware, donc ces trois entrées sont traitées correctement. Pour le côté regex, l’Aide-mémoire Regex couvre la classe Unicode \p{L}.
4. Pollution par guillemets typographiques
Collez une chaîne depuis Microsoft Word, Google Docs ou Notes macOS dans un convertisseur de casse et vous pouvez transporter des passagers invisibles : U+2018 / U+2019 / U+201C / U+201D (guillemets courbes), U+2014 (tiret cadratin), U+00A0 (espace insécable), U+200B (espace de largeur nulle). Tous ressemblent en tout point à leurs équivalents ASCII dans la plupart des polices mais s’encodent différemment. Un identifiant camelCase qui contient un U+00A0 compilera dans certains langages et pas dans d’autres, et votre grep sur le nom de la variable ratera silencieusement l’occurrence.
Défense : normalisez l’entrée avant de tokeniser. Un input.normalize('NFKC').replace(/[“”‘’]/g, '"') d’une ligne enlève la plupart des coupables. Ou utilisez l’approche du Guide du comparateur de texte — diffez la chaîne suspecte contre son jumeau ASCII visuel et repérez les invisibles dans une vue hex.
5. Les URL ne devraient pas être snake_case-ées
https://example.com/api/users collé dans un convertisseur snake_case produit https_example_com_api_users. Techniquement un identifiant snake_case valide ; sémantiquement un désastre. Les URL sont déjà dans leur case canonique (path/case avec des segments de chemin en kebab-case minuscule), et traiter l’URL entière comme un seul identifiant perd l’information structurelle.
La solution est de parser l’URL, extraire les segments de chemin et convertir chaque segment indépendamment si vous en avez vraiment besoin. Le Convertisseur de casse ne parse délibérément pas les URL automatiquement parce que deviner l’intention de l’utilisateur est plus dangereux que d’être littéral — collez une URL, obtenez une conversion littérale ; si vous vouliez un comportement segment-par-segment, faites-le vous-même.
6. dot.case versus accès aux propriétés
La chaîne user.profile.image est deux choses différentes selon le contexte. En tant qu’identifiant dot.case dans un fichier TOML, c’est un seul nom avec trois segments. En tant qu’expression JavaScript, c’est la propriété image de la propriété profile de user.
Si vous copiez une chaîne dot.case d’un fichier de configuration et la collez dans une console JavaScript, le runtime essaiera de l’évaluer comme une chaîne de propriétés et soit erreur, soit renvoie quelque chose de surprenant. Inversement, le code qui manipule des chaînes de chemins de propriétés JS ('a.b.c'.split('.')) finit parfois par traiter des identifiants dot.case venus d’ailleurs comme des chemins plus profonds que prévu. Les deux doivent rester namespacés.
Convention : les chaînes dot.case restent dans les données (fichiers de configuration, chemins MongoDB, clés de log) ; le code à un seul identifiant utilise camelCase ou snake_case ; si vous avez besoin d’un truc hiérarchique dans le code, utilisez des objets imbriqués et la syntaxe d’accès par point du langage hôte.
Recettes de migration entre langages
JS camelCase vers Python snake_case
Le workflow le plus rapide : copiez l’identifiant JS, collez dans un convertisseur, copiez la sortie snake_case. Pour une conversion au niveau du code en masse :
import { snakeCase } from 'change-case';
snakeCase('parseHTML'); // 'parse_html'
snakeCase('XMLHttpRequest'); // 'xml_http_request'
snakeCase('parseUTF8'); // 'parse_utf_8'
snakeCase('iPhone'); // 'i_phone'
Le dernier est le piège — iPhone est un nom de marque où la frontière camelCase est trompeuse. Pour les noms de marque et une poignée d’identifiants historiques, éditez à la main après la conversion.
SQL snake_case vers les réponses d’API JS/Java
La plupart des ORM le font pour vous automatiquement. Sequelize a underscored: true, TypeORM a la classe SnakeNamingStrategy, Hibernate a ImplicitNamingStrategyComponentPathImpl. Le mapping par défaut est user_profile_id ↔ userProfileId.
Ce qui casse : les colonnes portant un acronyme. Une colonne nommée http_status_code fait l’aller-retour vers httpStatusCode proprement, mais si votre base préfère HTTPStatusCode, l’ORM va lutter contre vous. Renommez la colonne en httpstatuscode_code (moche), configurez l’ORM pour préserver les acronymes (rare), ou acceptez la convention standard.
Composants PascalCase React vers 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) est la convention de classes CSS la plus courante qui s’apparie avec React : le bloc est le nom du composant en kebab-case, l’élément est block__element, le modificateur est block--modifier. Au niveau fichier : UserProfileCard.tsx pour le composant, UserProfileCard.module.css pour les styles scopés, tous deux en PascalCase, alignés avec le nom du composant.
Variables d’environnement vers config applicative
# .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'])
Le nom de la variable d’env reste en CONSTANT_CASE ; l’identifiant côté application suit la convention de variable du langage. Les clés de config YAML/TOML sont conventionnellement en snake_case (database_url, max_retries) même si elles mappent aux mêmes variables d’env CONSTANT_CASE à l’exécution — les frameworks comme Spring, dotenv et Pydantic gèrent la correspondance de case pour vous.
Comparaison des bibliothèques et outils
| Outil | Langages | Cases supportées | Comportement du tokeniseur |
|---|---|---|---|
lodash (_.camelCase, etc.) | JavaScript | 4 principales + startCase | Acronyme-comme-un-mot |
Paquet npm change-case | JavaScript/TS | Les 8 cases de programmation | Acronyme-comme-un-mot |
inflection (Python) | Python | camelCase / snake_case | Acronyme-comme-un-mot |
Crate convert_case | Rust | 12+ cases | Acronymes configurables |
Go strings + regex | Go | Fait main | Défini par projet |
| VS Code (intégré) | Éditeur | UPPER / lower / Title uniquement | Whitespace seulement |
| Extension VS Code « change-case » | Éditeur | Les 8 cases de programmation | Acronyme-comme-un-mot |
| Convertisseur de casse | Navigateur | 15 cases (7 texte + 8 code) | Acronyme-comme-un-mot |
Pour le code au quotidien, installez change-case (JS) ou convert_case (Rust). En Python, le paquet inflection est le choix canonique mais une petite regex écrite à la main couvre 90 % des cas. Pour les conversions ponctuelles pendant une revue de code ou un refactor, le Convertisseur de casse montre les 15 sorties en un seul collage pour que vous puissiez les comparer d’un coup d’œil. Si vous avez aussi besoin de compter des tokens ou de valider la longueur d’un identifiant, le Compteur de mots gère ce côté ; pour vérifier une regex de tokeniseur, utilisez le Testeur Regex avec les patterns de l’aide-mémoire lié plus haut.
FAQ
Quelle est la différence entre camelCase et PascalCase ?
camelCase commence par une lettre minuscule (userProfile) ; PascalCase commence par une majuscule (UserProfile). Les deux capitalisent chaque mot suivant sans séparateur. camelCase est la convention pour les variables et fonctions dans la plupart des langages de la famille C ; PascalCase est la convention pour les classes, types et composants React.
Pourquoi Python utilise-t-il snake_case alors que JavaScript utilise camelCase ?
Python (1991) a hérité de snake_case du C et du langage ABC, puis PEP 8 l’a codifié comme standard de la communauté. JavaScript (1995) a copié le style camelCase de Java, et Java avait hérité de camelCase de Smalltalk. Les deux sont des dépendances historiques. Aucune convention n’est techniquement meilleure — les études de lisibilité sont à peu près à égalité — et la cohérence au sein d’un écosystème compte plus que le choix lui-même.
Faut-il utiliser parseUrl ou parseURL pour les acronymes en camelCase ?
parseUrl (acronyme-traité-comme-un-mot) est le défaut moderne — utilisé par Google, Apple, lodash et le paquet npm change-case. parseURL (capitalisation préservée) est le style Microsoft .NET et domine dans le code C#. Pour un nouveau projet en JavaScript, TypeScript ou Swift, choisissez parseUrl parce qu’il fait l’aller-retour proprement à travers les conversions snake_case et kebab-case. Quoi que vous choisissiez, encodez-le dans votre linter.
kebab-case est-il meilleur que snake_case pour les URL ?
Oui. Le guide officiel de Google Search Central recommande d’utiliser des traits d’union, pas des tirets bas, dans les URL. Les indexeurs de recherche tokenisent sur les traits d’union mais pas sur les tirets bas : /user-profile est indexé comme user + profile, tandis que /user_profile est indexé comme le terme unique user_profile. L’impact sur le classement est petit par page mais réel, et les URL en kebab-case minuscule évitent aussi les bugs de sensibilité à la casse sur les serveurs Linux.
Quelle case faut-il utiliser pour les noms de colonnes de base de données ?
snake_case. Chaque ORM majeur (SQLAlchemy, Hibernate, Sequelize, TypeORM, Active Record) le prend par défaut, et chaque dialecte SQL majeur le gère de manière identique. PostgreSQL replie les identifiants non quotés en minuscules, MySQL est sensible à la casse sur Linux et insensible sur macOS/Windows, et SQLite traite les noms comme des chaînes opaques. snake_case minuscule est la seule orthographe qui se comporte pareil partout.
Peut-on mélanger des conventions de nommage dans un seul projet ?
Oui — et vous y êtes généralement obligé. Une appli web typique peut utiliser camelCase pour les variables JS, snake_case pour la base de données, kebab-case pour les classes CSS et URL, et CONSTANT_CASE pour les variables d’env. La règle est « une convention par couche, jamais de mélange au sein d’une même couche ». Encodez le choix par couche dans votre linter ou guide de style pour que les revues de PR cessent d’en parler.
Comment convertir entre les cases par programmation ?
En JavaScript et TypeScript, installez change-case ou utilisez _.camelCase / _.snakeCase / _.kebabCase de lodash. Côté Python, le paquet inflection ou une courte regex (re.sub(r'(?<!^)(?=[A-Z])', '_', s).lower() pour PascalCase vers snake_case). En Rust, le crate convert_case. Pour des conversions interactives ponctuelles, le Convertisseur de casse montre les 15 sorties pour toute entrée dans une seule page navigateur.
CONSTANT_CASE sert-il seulement aux variables d’environnement ?
Non, mais les variables d’env sont l’usage le plus courant. CONSTANT_CASE sert à tout « invariant d’exécution » : MAX_RETRIES, API_BASE_URL, DEFAULT_PAGE_SIZE, valeurs d’enum, définitions de macro, constantes de configuration globales. La règle est « est-ce que changer ça à l’exécution serait un bug ? » — si oui, CONSTANT_CASE ; si non, la convention de variable normale du langage. const result = await fetch(url) est très bien tel quel.
Quelle est la différence entre dot.case et path/case ?
dot.case utilise . comme séparateur (user.profile.image) et représente une clé hiérarchique au sein de données : packages Java, chemins de champs MongoDB, clés de configuration TOML, chemins get/set de Lodash. path/case utilise / (user/profile/image) et représente un emplacement réel : chemins d’URL, chemins du système de fichiers, refs Git. Le choix points-versus-slashes signale « étiquette de donnée » versus « emplacement réel ».
La fiche de décision en 30 secondes
Trois règles qui couvrent 95 % des questions :
-
Pour les identifiants de code, copiez la bibliothèque standard de votre langage. Python : snake_case pour les variables et fonctions, PascalCase pour les classes. JavaScript et TypeScript : camelCase pour les variables et fonctions, PascalCase pour les classes et composants. Go : minuscule en première lettre pour privé au package, majuscule en première lettre pour exporté. Rust : snake_case pour les variables et fonctions, PascalCase pour les types, SCREAMING_SNAKE pour les constantes.
-
Pour les couches transversales, la case est fixée quel que soit le langage. Les URL sont en kebab-case. Les classes CSS sont en kebab-case. Les noms de colonnes de base de données sont en snake_case. Les variables d’environnement sont en CONSTANT_CASE. Les en-têtes HTTP/1.1 sont en Header-Case (HTTP/2 normalise en minuscules sur le fil).
-
Écrivez le choix dans votre linter une bonne fois et arrêtez de débattre. ESLint, Pylint, Clippy, golangci-lint et Rubocop ont tous des règles pour ça. Choisissez la convention, configurez le linter, et la prochaine revue de PR ne perd plus un mot sur
userIDversususerId.
Quand vous devez convertir entre les cases — pour un refactor, une migration CMS, un mapping SQL-vers-API — le Convertisseur de casse vous donne les 15 sorties en un seul collage pour que vous puissiez copier la bonne sans tokeniser l’entrée à la main. Pour le travail texte connexe, voir le Compteur de mots, le Testeur Regex et le Comparateur de texte en ligne. Pour des lectures plus profondes, l’Aide-mémoire Regex couvre les patterns de tokeniseur, le Guide du comparateur de texte couvre les comparaisons avant/après pendant une migration, et le Guide des limites de caractères et de mots couvre les budgets de longueur d’URL pour les slugs SEO.