Styl nazewnictwa wybiera się według miejsca, w którym nazwa jest używana, a nie według upodobań. camelCase służy zmiennym i funkcjom w JavaScripcie, PascalCase klasom i komponentom, kebab-case adresom URL, plikom i klasom CSS, snake_case Pythonowi i bazom danych, a SCREAMING_SNAKE_CASE stałym i zmiennym środowiskowym. Ważniejsza od wyboru jest konsekwencja: jedna reguła na jedno miejsce w całym projekcie.
Tę samą frazę „user profile name” da się zapisać na siedem sposobów:
userProfileName(camelCase)UserProfileName(PascalCase)user-profile-name(kebab-case)user_profile_name(snake_case)USER_PROFILE_NAME(SCREAMING_SNAKE_CASE)User-Profile-Name(Train-Case)user.profile.name(dot.case)
Dlaczego konwencje nazewnictwa w kodzie mają znaczenie?
Nazwa zapisana zgodnie z konwencją niesie dodatkową informację. UserProfileCard sugeruje komponent, klasę albo typ. userProfileCard wygląda jak zmienna lub funkcja. USER_PROFILE_CARD od razu wskazuje stałą.
Koszt braku konwencji rośnie razem z projektem. Gdy jedna osoba pisze userProfile, druga user_profile, a trzecia tworzy plik user-profile.tsx, każdy zapis z osobna jest poprawny, ale zespół traci czas na szukanie plików, poprawki w przeglądach kodu i spory o rzeczy, które powinna rozstrzygać jedna strona dokumentacji. Kod czyta się wielokrotnie częściej, niż pisze, więc ta strata powtarza się przy każdej zmianie.
camelCase
Pierwsze słowo zaczyna się małą literą, każde kolejne wielką: userName, getUserProfile, isUserLoggedIn. Nazwa pochodzi od skojarzenia z garbami wielbłąda.
To domyślny zapis zmiennych, funkcji, metod, parametrów i właściwości obiektów w JavaScripcie, TypeScripcie, Javie i Kotlinie.
const userName = "Anna";
function getUserProfile() { return { name: userName }; }
camelCase sprawdza się tam, gdzie nazwa jest częścią logiki programu: jest zwięzły i nie wymaga separatorów. Nie pasuje do adresów URL, nazw plików i klas CSS. Zamiast userProfilePage.html lepiej zapisać user-profile-page.html.
PascalCase
Od camelCase różni się jednym: pierwsze słowo też zaczyna się wielką literą. Przykłady: UserProfile, PaymentService, OrderHistoryPage.
Tym stylem zapisuje się większe struktury w kodzie: klasy, komponenty, typy, interfejsy, enumy i modele danych.
class UserAccount { constructor(public userName: string) {} }
type UserProfile = { id: number; name: string };
W React to nie jest kwestia stylu. Według dokumentacji React nazwa komponentu musi zaczynać się wielką literą, inaczej komponent nie zadziała: zapis <section> React traktuje jako znacznik HTML, a <Profile /> jako komponent. Funkcja userProfileCard użyta jako komponent to więc błąd, a nie odstępstwo od konwencji.
PascalCase nie służy zwykłym zmiennym lokalnym. const UserName = "Anna"; wprowadza w błąd, poprawny zapis to const userName = "Anna";.
kebab-case
Same małe litery, słowa oddzielone łącznikami: user-profile, main-navigation, blog-post-card.
To zapis adresów URL, slugów, nazw plików i klas CSS:
- adres:
/blog/jak-nazywac-zmienne-w-kodzie - plik:
user-profile-page.html - klasa CSS:
.user-profile-card { padding: 16px; }
W adresach URL przemawia za nim także wyszukiwarka. Google w wytycznych o strukturze adresów zaleca łączniki zamiast podkreślników, bo ułatwiają użytkownikom i wyszukiwarkom rozpoznanie pojęć w adresie. /blog/style-nazewnictwa-w-programowaniu czyta się bez wysiłku, /blog/styleNazewnictwaWProgramowaniu już nie.
kebab-case nie nadaje się na nazwy zmiennych. W JavaScripcie łącznik jest operatorem odejmowania, więc const user-profile = "Anna"; kończy się błędem składni.
snake_case
Małe litery i podkreślniki między słowami: user_profile, get_user_profile, is_user_logged_in.
W Pythonie to standard zapisany w PEP 8: nazwy funkcji i zmiennych pisze się małymi literami, a słowa oddziela podkreślnikami. Klasy w Pythonie zapisuje się w PascalCase, który PEP 8 nazywa konwencją CapWords.
user_name = "Anna"
def get_user_profile(): return {"name": user_name}
snake_case dominuje też w bazach danych. Kolumny first_name, last_name i created_at w tabeli user_profiles są czytelne i nie wymagają cudzysłowów w zapytaniach SQL.
W JavaScripcie i TypeScripcie snake_case pojawia się głównie w danych przychodzących z API albo z bazy, na przykład z systemu headless CMS. Dobrą praktyką jest zamiana nazw na camelCase na granicy systemu, w jednym miejscu, zamiast mieszania obu stylów w całym kodzie.
SCREAMING_SNAKE_CASE
snake_case zapisany wielkimi literami: MAX_USER_COUNT, API_BASE_URL, DEFAULT_LANGUAGE.
Służy stałym, zmiennym środowiskowym i wartościom konfiguracyjnym. PEP 8 opisuje stałe tak samo: wielkie litery z podkreślnikami.
- stała w kodzie:
const MAX_RETRY_COUNT = 3; - zmienna środowiskowa:
DATABASE_URL=postgres://localhost:5432/app - zmienna środowiskowa:
NODE_ENV=production
Wielkie litery działają tylko wtedy, gdy są rzadkie. Jeśli każda zmienna, łącznie z USER_NAME i USER_EMAIL, jest zapisana w ten sposób, zapis przestaje cokolwiek komunikować.
Train-Case
kebab-case, w którym każde słowo zaczyna się wielką literą: Content-Type, Accept-Language, Cache-Control, User-Agent.
Najbardziej znane zastosowanie to nagłówki HTTP. Poza nimi styl jest rzadki i nie nadaje się na nazwy zmiennych, funkcji ani klas, z tego samego powodu co kebab-case: łącznik zostanie odczytany jako odejmowanie.
dot.case
Słowa oddzielone kropkami: auth.login.error, app.theme.color, settings.language.default.
Pasuje tam, gdzie nazwa ma strukturę hierarchiczną: w kluczach tłumaczeń, konfiguracji, nazwach metryk i zdarzeń analitycznych. Klucz auth.login.error czyta się jako obszar, ekran i komunikat.
W większości języków kropka ma znaczenie składniowe, więc dot.case nie może być nazwą zmiennej. const user.profile.name = "Anna"; jest błędem, poprawny odpowiednik to obiekt zagnieżdżony.
path/case
Słowa oddzielone ukośnikami: src/components/user-profile-card.tsx, api/users/profile. To zapis folderów, routingu i endpointów API, czyli sposób wskazania lokalizacji, a nie styl nazywania zmiennych. Poszczególne segmenty ścieżki najczęściej zapisuje się w kebab-case.
Title Case i Sentence case
Te dwa style dotyczą tekstów w interfejsie, a nie kodu. W Title Case każde ważne słowo zaczyna się wielką literą: Create New Account. W Sentence case wielką literą zaczyna się tylko pierwsze słowo: Create new account.
Decyzja należy do projektanta treści interfejsu i powinna być zapisana razem z konwencjami kodu, bo dotyczy każdego przycisku, etykiety i komunikatu. W polskiej wersji produktu wyboru nie ma: polska pisownia nie zna zapisu tytułowego, więc „Utwórz nowe konto” jest jedyną poprawną formą.
Który styl stosować w którym miejscu?
Pytanie wyjściowe brzmi: gdzie ta nazwa będzie używana. Odpowiedź wyznacza styl.
| Miejsce | Styl | Przykład |
|---|---|---|
| Zmienna i funkcja w JavaScripcie i TypeScripcie | camelCase | getUserProfile() |
| Klasa, typ, komponent React | PascalCase | UserProfileCard |
| Zmienna i funkcja w Pythonie | snake_case | get_user_profile() |
| Stała | SCREAMING_SNAKE_CASE | MAX_RETRY_COUNT |
| Zmienna środowiskowa | SCREAMING_SNAKE_CASE | DATABASE_URL |
| Adres URL i slug | kebab-case | /user-profile |
| Klasa CSS | kebab-case | .user-profile-card |
| Tabela i kolumna w SQL | snake_case | created_at |
| Klucz tłumaczenia, nazwa zdarzenia | dot.case | auth.login.error |
| Ścieżka pliku, endpoint | path/case | src/components/button |
| Nagłówek HTTP | Train-Case | Content-Type |
| Design token | ścieżka z kropkami w źródle, kebab-case w CSS | color.accent.light |
| Tekst w interfejsie | Sentence case | Create new account |
Ta sama zasada dotyczy nazw kluczy w formatach danych, takich jak JSON czy format TOON.
Jak nazywać tokeny i komponenty w design systemie?
W design systemie nazwa jest umową między projektantem a programistą, więc konwencja musi obejmować oba narzędzia. Komponent, który w bibliotece projektowej nazywa się „Button Group”, a w kodzie BtnGrp, wymaga tłumaczenia przy każdym przekazaniu projektu. Wspólna nazwa w PascalCase, ButtonGroup, usuwa ten krok. Które elementy nazwać w pierwszej kolejności, podpowiada wpis o komponentach design systemu.
Design tokeny, czyli nazwane wartości kolorów, odstępów i typografii, mają własne ograniczenia. Specyfikacja formatu Design Tokens Community Group rozróżnia wielkość liter i zabrania w nazwach tokenów i grup kropki oraz nawiasów klamrowych, bo te znaki służą do odwołań między tokenami. Ścieżkę tokena buduje się z nazw grup połączonych kropkami: color.accent.light. W CSS ten sam token staje się zmienną w kebab-case: --color-accent-light. Specyfikacja ostrzega też przed nazwami różniącymi się tylko wielkością liter, bo po eksporcie do innego języka dają duplikaty.
O strukturze i poziomach tokenów piszemy we wpisie o tym, czym są design tokeny.
Co się dzieje, gdy style są mieszane?
Najwięcej kosztuje brak reguły, a nie zły wybór. W tym fragmencie każda linia działa, ale razem nie mówią nic o tym, co oznaczają wielkie litery:
const user_name = "Anna";const userAge = 28;const UserEmail = "[email protected]";const USER_profile_status = "active";
Po ujednoliceniu do camelCase (userName, userAge, userEmail, userProfileStatus) kod czyta się bez zastanowienia. Reguły dla całego projektu mieszczą się w pięciu liniach: zmienne i funkcje w camelCase, komponenty i klasy w PascalCase, stałe w SCREAMING_SNAKE_CASE, pliki i adresy w kebab-case, baza danych w snake_case.
Taką listę zapisuje się w repozytorium i egzekwuje automatycznie, linterem w edytorze i w potoku wdrożeniowym. Reguła, której pilnuje tylko przegląd kodu, przestaje działać przy pierwszym napiętym terminie.
Wspólne nazwy w projekcie i w kodzie
W Squares konwencję nazw komponentów i tokenów ustalamy na początku pracy nad design systemem, razem z zespołem wdrożeniowym, żeby biblioteka projektowa i kod używały tych samych słów. Te same nazwy trafiają potem do kodu podczas wdrożenia aplikacji. Design system wyceniamy projektowo, od 12 000 zł netto.
Najczęstsze pytania
Czym różni się camelCase od PascalCase?
Jedną literą: w camelCase pierwsze słowo zaczyna się małą literą, w PascalCase wielką. camelCase służy zmiennym, funkcjom, metodom i właściwościom obiektów, a PascalCase większym strukturom: klasom, komponentom, typom i interfejsom. W React nazwa komponentu musi zaczynać się wielką literą, inaczej zostanie potraktowana jako znacznik HTML.
Jaki styl nazewnictwa stosować w adresach URL?
W adresach URL stosuje się kebab-case, czyli same małe litery i słowa oddzielone łącznikami, na przykład /user-profile. Google w wytycznych o strukturze adresów zaleca łączniki zamiast podkreślników, bo ułatwiają użytkownikom i wyszukiwarkom rozpoznanie pojęć w adresie. Ten sam zapis stosuje się w slugach, nazwach plików i klasach CSS.
