JSON, YAML, TOML은 소프트웨어 개발에서 가장 널리 사용되는 3가지 설정 형식입니다. 각각 다른 강점과 트레이드오프가 있습니다. 이 가이드는 프로젝트에 적합한 형식을 선택하는 데 도움이 되는 포괄적인 비교를 제공합니다.
각 형식 개요
JSON (JavaScript Object Notation)
JSON은 2000년대 초반 Douglas Crockford에 의해 도입되었습니다. 웹 API, package.json, tsconfig.json 등의 사실상 표준입니다.
YAML (YAML Ain't Markup Language)
YAML은 2001년에 제안되었으며 인간 가독성을 위해 설계되었습니다. Docker Compose, Kubernetes, Ansible, CI/CD 파이프라인에서 널리 사용됩니다.
TOML (Tom's Obvious Minimal Language)
TOML은 2013년 Tom Preston-Werner가 만든 최소한이며 모호하지 않은 설정 형식입니다. Rust(Cargo.toml), Python(pyproject.toml), Hugo의 표준입니다.
구문 비교
동일한 설정을 3가지 형식으로 표현합니다:
JSON
{
"server": {
"host": "localhost",
"port": 8080,
"debug": true
},
"database": {
"host": "db.example.com",
"port": 5432,
"name": "myapp",
"credentials": {
"username": "admin",
"password": "secret"
}
},
"features": ["auth", "logging", "cache"],
"max_connections": 100
}YAML
# Server configuration
server:
host: localhost
port: 8080
debug: true
# Database settings
database:
host: db.example.com
port: 5432
name: myapp
credentials:
username: admin
password: secret
features:
- auth
- logging
- cache
max_connections: 100TOML
# Server configuration
max_connections = 100
features = ["auth", "logging", "cache"]
[server]
host = "localhost"
port = 8080
debug = true
[database]
host = "db.example.com"
port = 5432
name = "myapp"
[database.credentials]
username = "admin"
password = "secret"기능 비교
| 기능 | JSON | YAML | TOML |
|---|---|---|---|
| 주석 | 없음 | 있음 (#) | 있음 (#) |
| 데이터 타입 | string, number, boolean, null, array, object | string, int, float, bool, null, date, array, map + 커스텀 태그 | string, integer, float, boolean, datetime, array, table |
| 가독성 | 중간—중괄호와 따옴표가 노이즈를 추가 | 높음—들여쓰기 기반의 깔끔한 구문 | 높음—INI 스타일, 명확한 섹션 |
| 엄격성 | 매우 엄격—후행 콤마나 주석 불가 | 느슨—암묵적 타이핑이 예상치 못한 동작 유발 | 엄격—명시적 타입, 최소한의 모호성 |
| 도구 지원 | 우수—모든 언어에서 네이티브 파서 지원 | 양호—주요 언어 모두에 파서 있음 | 양호—성장 중, Rust/Python/Go에서 강력 |
| 여러 줄 문자열 | 없음 (\n 이스케이프 시퀀스 사용) | 있음 (| 리터럴, > 폴드) | 있음 (트리플 쿼트 문자열) |
각 형식의 사용 시기
JSON을 사용할 때...
- REST API 구축 또는 사용
- package.json이나 tsconfig.json 작업
- 기계가 주로 읽는 데이터 저장
- 가장 넓은 도구 지원이 필요한 경우
- 다른 프로그래밍 언어 간 데이터 교환
// Typical JSON use cases
// package.json
{
"name": "my-app",
"version": "1.0.0",
"scripts": {
"dev": "next dev",
"build": "next build"
}
}
// tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"strict": true
}
}YAML을 사용할 때...
- Docker Compose나 Kubernetes 매니페스트 작성
- CI/CD 파이프라인 설정
- Ansible이나 Helm 사용
- 설정에 주석이 필요한 경우
- 인간 가독성이 최우선
# Docker Compose
services:
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
# GitHub Actions
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm testTOML을 사용할 때...
- Rust 프로젝트 설정 (Cargo.toml)
- Python 프로젝트 설정 (pyproject.toml)
- Hugo 사용
- 암묵적 타입 변환이 없는 명확한 형식이 필요한 경우
- 설정에 명확한 섹션/그룹이 있는 경우
# Cargo.toml (Rust)
[package]
name = "my-app"
version = "0.1.0"
edition = "2021"
[dependencies]
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
# pyproject.toml (Python)
[project]
name = "my-package"
version = "1.0.0"
requires-python = ">=3.9"
[tool.ruff]
line-length = 88
target-version = "py39"흔한 함정
YAML: 들여쓰기 문제
YAML은 들여쓰기로 구조를 정의합니다. 탭과 스페이스를 혼용하거나 들여쓰기 레벨이 일관되지 않으면 오류가 발생합니다.
# BAD: mixing tabs and spaces (invisible but breaks YAML)
services:
web: # tab character - YAML error!
image: nginx
# BAD: inconsistent indentation
services:
web:
image: nginx # 4 spaces here
ports: # 2 spaces here - error!
- "80:80"
# GOOD: consistent 2-space indentation
services:
web:
image: nginx
ports:
- "80:80"YAML: "노르웨이 문제"
YAML 1.1에서 따옴표 없는 NO, yes, on, off는 불리언 값으로 해석됩니다. 국가 코드 "NO"(노르웨이)는 false가 됩니다.
# The "Norway Problem" - YAML 1.1
countries:
- name: Norway
code: NO # Parsed as boolean false!
- name: Sweden
code: SE # Parsed as string "SE"
- name: Finland
code: FI # Parsed as string "FI"
# Other surprising boolean values in YAML 1.1:
truthy: yes # boolean true
falsy: no # boolean false
enabled: on # boolean true
disabled: off # boolean false
positive: TRUE # boolean true
negative: False # boolean false
# FIX: Always quote values that could be misinterpreted
countries:
- name: Norway
code: "NO" # Now correctly a string
- name: Sweden
code: "SE"
settings:
enabled: "yes" # Now correctly a stringJSON: 후행 콤마
JSON은 후행 콤마를 허용하지 않습니다. 마지막 요소 뒤에 콤마를 추가하면 파싱 오류가 발생합니다.
// BAD: trailing comma after last element
{
"name": "my-app",
"version": "1.0.0",
"private": true, // <-- trailing comma = PARSE ERROR
}
// BAD: trailing comma in array
{
"colors": [
"red",
"green",
"blue", // <-- trailing comma = PARSE ERROR
]
}
// GOOD: no trailing commas
{
"name": "my-app",
"version": "1.0.0",
"private": true
}TOML: 중첩 테이블 구문
TOML에서 깊은 중첩 구조는 장황해질 수 있습니다. 각 레벨에 자체 [section.subsection] 헤더가 필요합니다.
# TOML: deeply nested config can be verbose
[server]
host = "localhost"
[server.ssl]
enabled = true
[server.ssl.certificates]
cert = "/path/to/cert.pem"
key = "/path/to/key.pem"
[server.ssl.certificates.ca]
bundle = "/path/to/ca-bundle.pem"
# The same in YAML is more compact:
# server:
# host: localhost
# ssl:
# enabled: true
# certificates:
# cert: /path/to/cert.pem
# key: /path/to/key.pem
# ca:
# bundle: /path/to/ca-bundle.pem
# TOML inline tables can help for shallow nesting:
[server]
host = "localhost"
ssl = { enabled = true, cert = "/path/to/cert.pem" }변환 도구
형식 간 전환이 필요하신가요? 무료 온라인 변환기를 사용하세요:
자주 묻는 질문
JSON, YAML, TOML 중 파싱이 가장 빠른 것은?
JSON이 일반적으로 가장 빠릅니다. 단순하고 엄격한 문법 덕분에 파서가 고도로 최적화되어 있습니다. TOML도 명확한 구문으로 빠릅니다. YAML은 복잡한 사양으로 가장 느립니다.
JSON에서 주석을 사용할 수 있나요?
표준 JSON(RFC 8259)은 주석을 지원하지 않습니다. JSON5와 JSONC가 확장으로 주석을 지원하지만 비표준입니다.
왜 YAML은 "NO"를 false로 취급하나요?
YAML 1.1에서 yes/no, on/off, true/false는 불리언 값으로 인식됩니다. "NO"(노르웨이)는 false가 됩니다. 항상 따옴표로 감싸세요.
TOML이 YAML보다 설정 파일에 더 적합한가요?
TOML은 단순한 설정에 적합합니다. YAML은 깊은 중첩 구조에 적합합니다. 에코시스템에 따라 다릅니다.
형식 간 변환 시 데이터가 손실되나요?
일반적인 데이터 구조에서는 변환이 무손실입니다. YAML 앵커나 주석 등 형식 고유 기능은 JSON으로 변환 시 손실됩니다.