JSONL vs NDJSON: 차이점은?
JSONL(JSON Lines)과 NDJSON(Newline Delimited JSON)을 비교하는 완전 가이드 — 거의 동일한 형식의 두 이름이지만, 알아둘 가치가 있는 미묘한 차이점이 있습니다.
최종 업데이트: 2026년 2월
빠른 비교: JSONL vs NDJSON
| 기능 | JSONL (JSON Lines) | NDJSON |
|---|---|---|
| 전체 이름 | JSON Lines | Newline Delimited JSON |
| 파일 확장자 | .jsonl | .ndjson |
| 사양 | jsonlines.org (비공식) | github.com/ndjson/ndjson-spec (비공식 사양) |
| 출처 | 커뮤니티 관례, 데이터 사이언스 도구에 의해 대중화 | Chris Olah, Thorsten Ball 등이 제안 |
| 줄 구분자 | \n (줄바꿈) | \n (줄바꿈) |
| MIME 타입 | application/jsonl (비공식) | application/x-ndjson |
| 스트리밍 지원 | 예, 줄 단위 | 예, 줄 단위 |
| 채택 | OpenAI, Hugging Face, ML/AI 에코시스템 | Elasticsearch, Apache Spark, 데이터 엔지니어링 |
JSONL(JSON Lines)이란?
JSONL은 JSON Lines의 약자로, 각 줄에 하나의 유효한 JSON 값이 포함된 텍스트 기반 데이터 형식입니다. 줄은 줄바꿈 문자(\n)로 구분됩니다. 이 형식은 머신러닝 및 데이터 사이언스 커뮤니티에서 대중화되었으며, jsonlines.org에서 비공식적으로 정의되었습니다.
JSONL 파일은 .jsonl 파일 확장자를 사용합니다. 이 형식은 AI 및 ML 학습 데이터의 표준이 되었습니다 — OpenAI는 파인튜닝에 .jsonl 파일을 요구하며, Hugging Face 데이터셋은 일반적으로 JSON Lines 형식을 사용합니다.
{"id": 1, "text": "Hello world", "label": "greeting"}{"id": 2, "text": "How are you?", "label": "question"}{"id": 3, "text": "Goodbye", "label": "farewell"}
NDJSON(Newline Delimited JSON)이란?
NDJSON, 즉 Newline Delimited JSON은 각 줄이 줄바꿈 문자로 구분된 유효한 JSON 값인 데이터 형식입니다. 사양은 github.com/ndjson/ndjson-spec에 호스팅되어 있으며, 줄 구분 JSON 데이터에 대한 보다 구조화된 표준을 제공하기 위해 공식화되었습니다.
NDJSON 파일은 .ndjson 파일 확장자를 사용하고 application/x-ndjson의 등록된 MIME 타입을 갖습니다. 이 형식은 데이터 엔지니어링, 로그 처리 및 스트리밍 애플리케이션에서 널리 채택되었습니다 — Elasticsearch, Apache Spark 및 많은 HTTP 스트리밍 API가 NDJSON을 사용합니다.
{"id": 1, "text": "Hello world", "label": "greeting"}{"id": 2, "text": "How are you?", "label": "question"}{"id": 3, "text": "Goodbye", "label": "farewell"}
JSONL과 NDJSON은 같은 형식인가요?
실제로 그렇습니다 — JSONL과 NDJSON은 기능적으로 동일한 형식입니다. 둘 다 줄바꿈 문자(\n)로 구분된 줄당 하나의 JSON 값을 저장합니다. 동일한 데이터를 가진 .jsonl 파일과 .ndjson 파일은 완전히 호환되며, 한 형식을 읽을 수 있는 도구는 다른 형식도 읽을 수 있습니다.
차이점은 순전히 명명, 커뮤니티 채택 및 메타데이터 관례에만 있습니다. JSONL(JSON Lines)은 데이터 사이언스 및 머신러닝 커뮤니티에서 등장했고, NDJSON(Newline Delimited JSON)은 데이터 엔지니어링 및 웹 스트리밍 커뮤니티에 의해 공식화되었습니다. "movie"와 "film"처럼 생각하세요 — 같은 것이지만, 다른 그룹에서 다른 이름 선호도를 가집니다.
가장 의미 있는 차이점은 파일 확장자(.jsonl vs .ndjson)와 MIME 타입입니다. NDJSON은 HTTP 스트리밍 컨텍스트에서 사용되는 더 널리 인정받는 MIME 타입(application/x-ndjson)을 가지고 있고, JSONL 파일은 AI/ML 워크플로우의 표준입니다. 둘 중 선택할 때는 해당 에코시스템의 관례를 따르세요.
JSONL과 NDJSON의 주요 차이점
1. 사양 & 권위
간결하고 비공식적인 사양으로 jsonlines.org에 정의되어 있습니다. 사양은 간단합니다: 각 줄은 유효한 JSON 값이고, 줄은 '\n'으로 구분되며, UTF-8 인코딩이 권장됩니다.
약간 더 공식적인 사양으로 github.com/ndjson/ndjson-spec에 정의되어 있습니다. NDJSON은 각 줄이 유효한 JSON 값이어야 하고 줄 구분자가 '\n'('\r\n'이 아님)이어야 하며, 후행 줄바꿈이 권장된다고 명시적으로 요구합니다.
2. 파일 확장자
.jsonl 파일 확장자를 사용합니다. 이것은 OpenAI 파인튜닝 파일, Hugging Face 데이터셋 및 대부분의 ML/AI 도구의 표준입니다. GitHub와 VS Code는 구문 강조 기능이 있는 .jsonl 파일을 인식합니다.
.ndjson 파일 확장자를 사용합니다. 이것은 데이터 엔지니어링 도구, Elasticsearch bulk API 및 스트리밍 HTTP 응답에서 일반적입니다. 많은 편집기도 .ndjson 구문 강조를 지원합니다.
3. MIME 타입
공식적으로 등록된 MIME 타입이 없습니다. 일반적인 비공식 타입에는 application/jsonl 및 application/json-lines가 포함됩니다. 실제로 많은 시스템은 application/jsonl을 사용하거나 application/json으로 폴백합니다.
application/x-ndjson을 MIME 타입으로 사용합니다. 이것은 HTTP 컨텍스트에서 더 널리 인정받으며 Elasticsearch, Fetch API 스트리밍 표준 및 스트리밍 응답을 위한 다양한 웹 프레임워크에서 사용됩니다.
4. 커뮤니티 & 에코시스템 채택
AI/ML 에코시스템에서 지배적입니다. OpenAI, Anthropic, Google Gemini, Hugging Face 및 대부분의 ML 프레임워크는 .jsonl을 사용합니다. 'JSONL'이라는 용어는 전반적으로 개발자 커뮤니티에서 더 일반적으로 검색되고 인식됩니다.
데이터 엔지니어링 및 백엔드 시스템에서 선호됩니다. Elasticsearch, Apache Spark, PostgreSQL COPY 및 많은 로그 집계 도구가 NDJSON을 사용합니다. ndjson npm 패키지는 매주 수백만 건의 다운로드가 있습니다.
JSONL vs NDJSON을 언제 사용할까요
- OpenAI, Anthropic 또는 기타 LLM 파인튜닝을 위한 학습 데이터 준비
- Hugging Face 데이터셋 작업
- ML 파이프라인 및 데이터 전처리 구축
- 팀 또는 문서가 'JSON Lines'를 참조하는 경우
- .jsonl 확장자를 예상하는 AI/ML 플랫폼에 파일 업로드
- Python 데이터 사이언스 환경에서 작업
- HTTP를 통한 JSON 데이터 스트리밍(Server-Sent Events, fetch 스트리밍)
- Elasticsearch bulk API 작업
- Apache Spark 또는 유사한 도구로 데이터 파이프라인 구축
- Content-Type 헤더 설정(application/x-ndjson)
- 인프라 또는 팀이 NDJSON 관례를 사용하는 경우
- Node.js 스트리밍 라이브러리 작업
코드 예제: JSONL과 NDJSON 읽기
# JSONL 읽기 - NDJSON 읽기와 정확히 동일import jsonwith open('data.jsonl', 'r') as f:for line in f:record = json.loads(line.strip())print(record['text'])# 출력:# Hello world# How are you?# Goodbye
// NDJSON 읽기 - JSONL 읽기와 정확히 동일import { createReadStream } from 'fs';import { createInterface } from 'readline';const rl = createInterface({input: createReadStream('data.ndjson')});for await (const line of rl) {const record = JSON.parse(line);console.log(record.text);}// 출력:// Hello world// How are you?// Goodbye