camelCase, snake_case, kebab-case 언제 쓸까: 개발자 명명 규칙 치트시트

짧게 정리하면 이렇습니다. 타입과 클래스는 거의 모든 언어에서 PascalCase를 씁니다. 변수와 함수는 JavaScript, Java, C#, Kotlin, Swift에서는 camelCase를, Python, Ruby, Rust에서는 snake_case를 씁니다. 상수는 대부분의 언어에서 SCREAMING_SNAKE_CASE를 쓰고, Go, Swift, C#, Google 스타일 C++이 예외입니다. URL, CSS 파일, 패키지 이름에 들어가는 이름은 대개 소문자 kebab-case이고, 환경 변수는 밑줄로 연결한 대문자입니다.
이것이 큰 흐름입니다. 코드 리뷰에서 논쟁이 벌어지는 곳은 세부 사항이므로, 이 치트시트는 각 언어의 공식 스타일 가이드나 가장 널리 쓰이는 가이드가 실제로 말하는 내용만 다루고 언어마다 출처를 밝혔습니다.
camelCase, snake_case, kebab-case: 다섯 가지 스타일과 다른 이름들
- camelCase(
orderTotal): 첫 단어는 소문자로, 이후 모든 단어는 첫 글자를 대문자로 씁니다. lowerCamelCase라고도 하며, PEP 8은 mixedCase라고 부릅니다. - PascalCase(
OrderTotal): 모든 단어의 첫 글자를 대문자로 씁니다. UpperCamelCase, CapWords(PEP 8), StudlyCaps(PHP의 PSR-1)라고도 합니다. - snake_case(
order_total): 소문자 단어를 밑줄로 연결합니다. - SCREAMING_SNAKE_CASE(
ORDER_TOTAL): 대문자 단어를 밑줄로 연결합니다. Google의 JavaScript 가이드는 CONSTANT_CASE, Java 가이드는 UPPER_SNAKE_CASE라고 부릅니다. - kebab-case(
order-total): 소문자 단어를 하이픈으로 연결합니다. 하이픈은 빼기 기호이기 때문에 대부분의 언어에서는 식별자에 쓸 수 없습니다.
이름을 다른 스타일로 바꾸려면 저희 대소문자 변환기에 붙여넣으세요. 공백, 밑줄, 하이픈, 기존 대문자를 기준으로 단어를 나누므로 order_total, order-total, OrderTotal이 서로 깔끔하게 변환됩니다. 다만 한 번에 이름 하나씩만 변환하세요. 입력란에 있는 내용 전체를 식별자 하나로 취급하기 때문입니다.
치트시트: 언어별 명명 규칙
| 언어 | 변수와 함수 | 클래스와 타입 | 상수 | 출처 |
|---|---|---|---|---|
| JavaScript, TypeScript | camelCase | PascalCase | 값이 바뀌지 않는 모듈 수준 값에는 CONSTANT_CASE | Google JavaScript 및 TypeScript 스타일 가이드 |
| Java | camelCase | PascalCase | 완전히 불변인 static final 필드에는 UPPER_SNAKE_CASE | Google Java Style Guide |
| Kotlin | camelCase | PascalCase | const와, 완전히 불변인 최상위 또는 object 값에는 SCREAMING_SNAKE_CASE | Kotlin coding conventions |
| C# | 지역 변수와 매개변수는 camelCase, private 필드는 _camelCase, 메서드와 public 멤버는 PascalCase | PascalCase, 인터페이스에는 I 접두사(IWorkerQueue) | PascalCase | Microsoft .NET 문서 |
| Swift | camelCase | PascalCase | camelCase | Swift API Design Guidelines |
| Go | 공개하지 않으면 camelCase, 공개하면 PascalCase | 같은 규칙 | MixedCaps도 사용(MaxPacketSize) | Effective Go, Google Go Style |
| Python | snake_case | PascalCase(CapWords) | UPPER_SNAKE_CASE | PEP 8 |
| Ruby | snake_case | PascalCase | SCREAMING_SNAKE_CASE | Ruby Style Guide |
| Rust | snake_case | PascalCase(UpperCamelCase) | SCREAMING_SNAKE_CASE | Rust API Guidelines (RFC 430) |
| PHP | 메서드는 camelCase, 속성은 정해진 규칙 없음 | PascalCase(StudlyCaps) | 클래스 상수는 UPPER_SNAKE_CASE | PSR-1 |
| C++ | 변수는 snake_case, 함수는 PascalCase | PascalCase | kDaysInAWeek | Google C++ Style Guide(여러 가이드 중 하나) |
몇몇 행에는 설명이 필요합니다. Go에서 첫 글자는 스타일 선택이 전혀 아니고 공개 범위 규칙입니다. Area는 패키지 밖으로 공개되고 area는 공개되지 않으며, 컴파일러가 이를 강제합니다. C++에는 언어 전체에 통하는 관례가 없습니다. 표준 라이브러리부터 snake_case를 쓰므로(std::unordered_map, push_back), Google 행은 규칙이 아니라 문서화가 잘된 선택지 중 하나로 보세요.
Rust는 스타일에 유난히 엄격합니다. 컴파일러가 기본으로 경고를 냅니다. fn GetUser()나 struct user_account라고 쓰면 린터를 돌리기도 전에 rustc가 get_user와 UserAccount를 제안합니다.
파일, 모듈, 패키지 이름
- Java: public 최상위 클래스는 대소문자까지 포함해 클래스 이름과 정확히 같은 이름의 파일에 있어야 합니다.
OrderService는OrderService.java에 두며, 다르면 javac가 거부합니다. - Kotlin: 클래스 하나가 든 파일은 그 클래스 이름을 따릅니다. 그 밖의 파일에는
ProcessDeclarations.kt처럼 내용을 설명하는 UpperCamelCase 이름을 붙입니다. - Python: 모듈은 짧은 전체 소문자 이름을 쓰고, 읽기에 도움이 되면 밑줄을 씁니다. 패키지도 짧은 소문자로 짓는 것이 좋고, PEP 8은 패키지 이름에 밑줄을 쓰지 않도록 권합니다.
- Ruby: 파일 이름은 안에 든 클래스 이름을 따른 snake_case입니다. 그래서
HelloWorld는hello_world.rb에 있습니다. - Go: 패키지 이름은 밑줄이나 mixedCaps가 없는 소문자 한 단어입니다.
encoding_base64나encodingBase64가 아니라base64입니다. - JavaScript와 TypeScript: 하나로 정해진 규칙은 없습니다. Google의 JavaScript 가이드는 밑줄이나 대시를 쓴 전체 소문자 파일 이름을 원하고, TypeScript 가이드는 snake_case를 씁니다. Airbnb 가이드는 파일 이름이 기본 export와 같아야 한다고 하므로
CheckBox클래스는CheckBox.js에 있습니다. 프로젝트마다 하나를 정해서 문서로 남기세요. - npm 패키지: 새 패키지 이름에는 대문자를 아예 쓸 수 없습니다.
소스 코드 너머: 환경 변수, CSS, HTML, URL, JSON, SQL
| 사용처 | 규칙 | 예 | 이유 |
|---|---|---|---|
| 환경 변수 | SCREAMING_SNAKE_CASE | DATABASE_URL | PATH, HOME 같은 시스템 변수와 맞춥니다. 이름은 Linux와 macOS에서는 대소문자를 구분하고 Windows에서는 구분하지 않습니다. |
| CSS 속성 | kebab-case | background-color | 언어가 정해 둔 형식입니다. |
| CSS 사용자 지정 속성 | 대시 두 개 뒤에 kebab-case | --brand-color | 대소문자를 구분하므로 --Brand-Color는 다른 속성이 됩니다. |
| CSS 클래스 이름 | kebab-case, 종종 BEM과 함께 | card__title--large | 주변의 속성들과 비슷하게 읽힙니다. |
| JavaScript에서 다루는 CSS | camelCase | el.style.backgroundColor | style 객체가 camelCase로 바뀐 속성 이름을 제공합니다. |
| HTML data 속성 | kebab-case | data-index-number | JavaScript에서는 dataset.indexNumber로 읽습니다. |
| URL 경로 | 소문자 kebab-case | /blog/developer-case-styles | Google은 밑줄보다 하이픈을 권하며, /APPLE과 /apple을 서로 다른 URL로 취급합니다. |
| JSON 키 | 표준 없음 | userId 또는 user_id | 주로 쓰는 쪽에 맞추고, 경계에서 변환하세요. |
| SQL 테이블과 열 | 소문자 snake_case | order_items | 주요 데이터베이스 모두에서 따옴표 없이 동작합니다. |
환경 변수에는 특이한 점이 하나 있습니다. POSIX는 표준 유틸리티가 대문자 이름을 쓴다고 하고, 소문자가 들어간 이름은 애플리케이션용으로 남겨 두므로 소문자 이름은 표준 이름과 절대 충돌하지 않습니다. 그래도 대문자가 굳어진 관행이므로, 저희라면 대문자를 유지하고 대신 MYAPP_TIMEOUT처럼 눈에 띄는 접두사를 붙여 충돌을 피하겠습니다.
CSS와 SQL 행은 각각 별도의 글이 있습니다. 클래스 이름은 CSS 명명과 BEM을, 데이터베이스가 왜 소문자 쪽으로 이끄는지는 SQL 명명 규칙을 보세요.
약어: 스타일 가이드의 의견이 갈리는 곳
모든 가이드가 userName에는 동의합니다. 의견이 갈리는 것은 userID입니다. Google의 JavaScript와 Java 가이드는 약어를 일반 단어처럼 소문자로 씁니다(xmlHttpRequest, customerId). Go는 약어 하나 안에서는 대소문자를 통일합니다(ServeHTTP, appID). Microsoft의 .NET 가이드라인은 두 글자 약어는 두 글자 모두 대문자로 쓰지만(IOStream) 더 긴 약어는 첫 글자만 대문자로 씁니다(HtmlTag). Rust는 약어를 단어로 취급하고(Uuid), PEP 8은 HttpServerError보다 HTTPServerError를 선호합니다. 이 선택지들을 나란히 비교한 글은 camelCase와 PascalCase 차이입니다.
잘 모르겠을 때 고르는 방법
- 플랫폼이 대신 정해 주는지 확인하세요. CSS 속성 이름, Java 파일 이름, Go의 공개 이름, React 컴포넌트 이름(대문자로 시작해야 합니다)은 스타일 선택이 아닙니다.
- 언어의 공식 가이드를 따르세요. 새 코드는 바로 옆에 있는 표준 라이브러리처럼 보여야 합니다.
- 기존 프로젝트에 맞추세요. PEP 8이 분명하게 말합니다. 프로젝트 안에서의 일관성이 스타일 가이드와의 일관성보다 중요합니다.
- 린터가 기억하게 하세요. ESLint의
camelcase규칙, Python용 Ruff의N규칙, rustc에 내장된 경고가 리뷰어가 보기 전에 실수를 잡아 줍니다. - 경계에서 한 번만 변환하세요. snake_case JSON이 camelCase JavaScript를 만나면, 두 스타일이 코드베이스 곳곳으로 새어 들어가게 두지 말고 직렬화 계층 한 곳에서 키 이름을 바꾸세요.


