jsonlkit.com
JSONL (JSON Lines) utilities, in the browser
Say hi →

NDJSON vs JSONL

Naming, history, edge cases · updated 22 May 2026 · what is NDJSON · what is JSONL · vs JSON / CSV / Parquet

NDJSON and JSONL are the same format. Same on-disk bytes, same parser, same MIME type, same use cases. The difference is the name and which ecosystem promotes it: NDJSON in JavaScript / observability / HTTP streaming, JSONL in Python / data engineering / ML. If you receive a file labeled one way and your tool expects the other, just rename the extension — there is no content-level conversion.

The short answer

All three: one JSON value per line, separated by \n, UTF-8, no enclosing array.

Side-by-side

AspectNDJSONJSONL
Full nameNewline-Delimited JSONJSON Lines
Spec sitegithub.com/ndjson (community)jsonlines.org
File extension.ndjson.jsonl
MIME typeapplication/x-ndjsonapplication/x-ndjson (most common); also application/jsonl
EncodingUTF-8UTF-8
Line separator\n\n
Per-line ruleOne valid JSON valueOne valid JSON value
Origin year~2013~2013
Dominant ecosystemJavaScript / Node / npm, observability, HTTP streamingPython, ML training (HuggingFace, OpenAI fine-tunes), data engineering
Where you'll see itElasticsearch _bulk, OpenAI / Anthropic streaming responses, pino / structlog / Vector / Fluentbit, D3 streamsOpenAI / Anthropic / Gemini / Llama / Mistral fine-tune datasets, HuggingFace datasets, BigQuery / Snowflake / DuckDB bulk imports
Common npm / pip namendjson, ndjson-clijsonlines (PyPI), jsonl (Cargo)
Spec coverage of blank linesSilent (most parsers tolerate)Silent (most parsers tolerate)
Spec coverage of trailing newlineRecommended, not requiredRecommended, not required
Compressed extension.ndjson.gz, .ndjson.zst.jsonl.gz, .jsonl.zst

The same file with both extensions

$ cat data.ndjson
{"id":1,"name":"Ada"}
{"id":2,"name":"Babbage"}

$ mv data.ndjson data.jsonl
$ cat data.jsonl
{"id":1,"name":"Ada"}
{"id":2,"name":"Babbage"}

Same bytes, two names. There is nothing to convert. The NDJSON ↔ JSONL normalizer exists only to clean up tangentially-related issues (BOM, CRLF, blank lines) and to let you download with either extension in one click.

Are there any differences in practice?

None at the format level. The minor practical differences come from each community's habits, not the format itself:

If you stick to the conformance checklist (UTF-8 no BOM, \n endings, one minified JSON value per line, same shape every line, trailing newline), every NDJSON and JSONL consumer in the world will accept the file.

History

Both names emerged around 2013, formalizing conventions that had been in use for years:

Which name should I use?

Pragmatic guidance:

Will my tool work on both?

Almost certainly yes. Every parser worth using treats .ndjson and .jsonl identically. The few exceptions are usually tools that whitelist extensions (e.g., a CLI that only accepts .jsonl by name). In that case: rename the file. The bytes are identical.

This site's tools all accept both. The file pickers list both extensions; the validators flag the same issues; the converters output content that's valid under either name.

Conformance checklist (applies to both)

Run any file through the NDJSON validator (or the equivalent JSONL validator) to check it against these rules.

FAQ

Should I migrate from NDJSON to JSONL (or vice versa)?

No migration is needed. The bytes are identical. If a tool requires a specific extension, rename the file. If you want to be community-aligned, match the dominant name in your ecosystem (NDJSON for JS / observability, JSONL for Python / ML / data).

Are there parsers that handle one but not the other?

Not at the format level. A few CLI tools whitelist extensions and will refuse a renamed file based on the extension string, not the bytes. That's a UX choice in the tool, not a format difference.

What's the difference in MIME type?

There isn't one in practice. application/x-ndjson is the universally-recognized MIME type for both names. application/jsonl appears in a handful of newer specs but is rarely used. Stick with application/x-ndjson.

Why two names?

Two independent communities formalized the same convention at around the same time, each producing a small website and a family of libraries. Neither could displace the other; both stuck. It's a Stigler's-law situation — neither name was "first" in any clean sense.

Where does LDJSON fit?

LDJSON ("Line-Delimited JSON") was an early name used briefly around 2012–2013. It got displaced by both NDJSON and JSONL and is rarely seen today. If you encounter an .ldjson file, treat it as either of the others.

— S., [email protected]