Developer Tool

JSON to JSONL Converter

Turn a JSON array into newline-delimited records for BigQuery, Elasticsearch, Kafka, and ML datasets, with stats and warnings included.

Data engineers, backend developers, and ML practitioners regularly hold a JSON array but need newline-delimited records: BigQuery load jobs reject a bracketed array, the Elasticsearch bulk API wants one document per line, and fine-tuning datasets specify JSONL by name. When to use it: Preparing an export for a bulk loader, reshaping an API response into log lines, converting a fixture file before running it through a streaming tool, or checking how many records an array actually contains before it lands in a pipeline. What it solves: Parses and validates your JSON, serializes each element as one compact line, reports record count, byte totals, and line lengths, and warns when elements are not the objects the target loader expects. Why it matters: Framing mistakes in line-based formats fail loudly at ingest time or, worse, split records silently. Converting in the browser keeps unreleased datasets and customer records off third-party servers.

How JSON to JSONL Conversion Works

The converter runs one JSON.parse over the entire input first. This single parse is both validation and structure detection: if it throws, the parser message is surfaced with no partial output; if it succeeds, the tool knows whether the root value is an array, an object, or a scalar and can choose the right record boundaries.

For an array root, each element is passed to JSON.stringify on its own. JSON.stringify never emits literal newlines for valid data, escaping any newline characters inside strings as \n, so every record is guaranteed to occupy exactly one physical line. Nested objects and arrays stay intact inside their line because they are serialized as part of that element, not split apart.

Stats are computed from the generated lines: record count, UTF-8 byte total via TextEncoder, and shortest, longest, and average line lengths in characters. The longest line matters because several streaming systems set per-record buffer sizes, and one bloated record can exceed them even when the average looks fine.

Warnings inspect the parsed structure rather than the text: an empty array, a root object that will become a single line, scalar elements that strict loaders reject, and a trailing-newline sanity check on the assembled output. Warnings are advisory by design, because NDJSON itself allows any JSON value per line while individual consumers impose stricter rules.

Before / After Examples

Example 1: Array of Records

Before (Bracketed JSON array)

[
  { "id": 1, "name": "Ada" },
  { "id": 2, "name": "Grace" }
]

<!-- BigQuery rejects the brackets -->

After (One object per line)

{"id":1,"name":"Ada"}
{"id":2,"name":"Grace"}

records: 2 · no brackets · no commas

Example 2: Nested Structure Stays on One Line

Before (Deeply nested array element)

[
  {
    "event": "login",
    "meta": { "ip": "10.0.0.5", "ua": "curl" }
  }
]

After (Compact single-line record)

{"event":"login","meta":{"ip":"10.0.0.5","ua":"curl"}}

1 record · nesting preserved inside the line

Example 3: Single Object Input

Before (Root object, not an array)

{ "batch": true, "items": 3 }

<!-- No array to iterate -->

After (Single line + warning)

{"batch":true,"items":3}

⚠ 1 record only — wrap records in an
  array for multi-line JSONL

Use Cases

Developer Production Workflow
Reshape an API response array for the Elasticsearch bulk endpoint Stage records for a BigQuery table load job Convert a test fixture before adding it to a repo
Turn sample objects into JSONL for a fine-tuning script Feed line-based log shippers from structured exports Count and inspect records before a migration sign-off
Check line lengths before setting Kafka buffer sizes Prepare CSV-alternative bulk files for Mongo exports Hand a data set to a teammate in the exact expected shape
Verify scalar elements get flagged before loader rejection Diff record counts between API pages and final loads Document the NDJSON convention for an integration guide

Common Mistakes & Troubleshooting

Leaving commas at the end of lines

Stripping the outer brackets of an array but keeping the commas between objects produces invalid JSONL, because each line is then parsed as a complete document and a trailing comma is a syntax error. The converter removes brackets and commas together by serializing each element separately.

❌ {"id":1},
   {"id":2}
✅ {"id":1}
   {"id":2}

Pretty-printing each record

Indented records span multiple physical lines, so a line-based reader treats fragment two as a separate document and fails immediately. JSONL records must be compact. Use a formatter after loading, not before.

❌ {
     "id": 1
   }          ← 3 physical lines
✅ {"id":1}   ← 1 record, 1 line

Assuming JSONL and CSV are interchangeable

JSONL preserves nested types (objects, arrays, booleans, null) while CSV is flat and needs quoting rules for embedded commas. Loading a delimited file into a JSONL pipeline, or the reverse, fails schema checks. Convert through the dedicated CSV tools when the target wants rows.

❌ data.csv → Elasticsearch bulk (newline JSON expected)
✅ CSV → CSV-to-JSON first, then convert to JSONL

Adding a UTF-8 BOM before the first record

A byte order mark at the start of the file becomes part of the first record for parsers that do not strip it, causing an unexpected token error on line one. Save JSONL files as plain UTF-8 without BOM, and watch for it when a file was edited on Windows.

❌ EF BB BF {"id":1}   ← BOM breaks line 1
✅ {"id":1}            ← plain UTF-8

Feeding scalars to an object-only loader

An array like [1, 2, 3] converts to three valid JSONL lines, but BigQuery and the Elasticsearch bulk API expect objects and will reject scalar documents. The warnings panel flags this so you can wrap the values instead of discovering it in a failed job.

❌ [1,2,3] → bulk loader expecting objects
✅ [{"value":1},{"value":2},{"value":3}]

Best Practices

✓

Keep records compact, format after load

Store and transmit JSONL as single-line records. Pretty-print in your editor or viewer once the data is loaded, never in the file itself.

✓

Watch the longest line, not just the count

Streaming buffers key off maximum record size. Use the stats panel to catch one oversized document before it trips a pipeline limit.

✓

Name files .jsonl or .ndjson

The extension signals the format to editors, linters, and loaders, and prevents a line-based file from being opened as one broken JSON document.

✓

Validate line by line after any edit

One hand-edited line can break the whole file. Re-parse every line after changes and confirm the valid-line count matches the total.

✓

Convert inside the browser for private data

Exports often contain emails, identifiers, or credentials. Client-side conversion means those rows never reach a third-party converter server.

✓

Standardize one record shape per file

Loaders infer schema from early records. Mixed shapes in one file cause type errors downstream, so normalize fields before converting.

✓

End the file with a newline

POSIX tools and many appenders expect a trailing newline so the last record is not merged with future appends. Add one if your pipeline does.

✓

Round-trip before shipping

Convert JSON to JSONL, then parse the result line by line. If every line parses and the record count matches, the framing is sound.

Frequently Asked Questions

What is the difference between JSON, NDJSON, and JSONL? +

Standard JSON is a single document that can hold an array of records wrapped in brackets with commas between them. NDJSON (Newline Delimited JSON) and JSON Lines (JSONL) put one complete JSON value on each line with no brackets and no commas joining the lines. The three names describe the same line-based convention, and files usually carry the .ndjson or .jsonl extension to signal that each line can be parsed on its own.

Which systems expect JSONL or NDJSON input? +

The Elasticsearch bulk API, Google BigQuery load jobs, Apache Kafka topics, AWS Kinesis and Firehose streams, MongoDB exports, and most structured logging pipelines read newline-delimited records. Machine learning datasets for fine-tuning also use JSONL, where each line is one training example. These systems stream line by line, which is why they reject a single bracketed array or a trailing comma.

How does this converter split my array into lines? +

The input is parsed once with JSON.parse to confirm it is valid, then every element of the top-level array is serialized independently with JSON.stringify, which produces compact one-line output without pretty-print whitespace. A single object input becomes a single line, and scalar inputs become one line each. The output joins the lines with newline characters and reports record counts and line lengths.

Why does my output look squashed compared to my input? +

JSONL readers commonly load one line at a time, so each record must fit on a single line. Pretty-printed JSON with indentation would span many physical lines per record and break the framing. The converter therefore emits compact records, and the stats panel shows the longest line so you can watch for oversized records that might hit buffer limits in streaming systems.

Can I convert an array of scalars or nested arrays? +

Yes, the converter will emit one line per element regardless of type, but the warnings panel flags when top-level elements are scalars or arrays instead of objects. BigQuery and the Elasticsearch bulk API expect object records, so scalar lines are valid JSONL yet often rejected by those specific loaders. Wrap bare values in an object first if the target system requires it.

Does the tool validate each output line? +

After building the output, the converter checks that no line contains an embedded newline, and the stats panel reports records, total bytes, and the shortest and longest line lengths. You can also paste the generated output back into the JSONL validation mode of related tools to parse every line independently and confirm the framing survived a round trip.

Is my data uploaded during conversion? +

No. Parsing and serialization happen inside the page with native JSON APIs. The array is never posted to a server, never logged, and never stored, which makes the converter safe for internal exports, customer records, and credentials that appear in API responses. Closing the tab discards the input and the generated lines.