Skip to main content
4 min read
•By Chieyine Nelson•Published August 15, 2026

Convert CSV to NDJSON (JSON Lines) Without Losing Record Boundaries

Turn CSV rows into newline-delimited JSON, understand type and null handling, and validate the result before using it in an API or data pipeline.

NDJSON stores one JSON value on each line. That small difference from an ordinary JSON array makes it useful for logs, command-line processing, bulk API requests, and pipelines that should handle one record at a time.

For a CSV, the natural mapping is one row to one JSON object. The header supplies the keys. Every subsequent row supplies the values.

order_id,customer,total,status
1001,Ada Okafor,12500.50,paid
1002,Musa Bello,7800,pending

becomes:

{"order_id":"1001","customer":"Ada Okafor","total":"12500.50","status":"paid"}
{"order_id":"1002","customer":"Musa Bello","total":"7800","status":"pending"}

There is no opening bracket, closing bracket, or comma between the records. Each line must stand on its own as valid JSON.

Convert the file

Open CSV to NDJSON, choose the source file, and confirm the delimiter and header row. HappyCSV processes the file locally in your browser and creates one object for each data row.

Download the result with the extension expected by the receiving system. Both .ndjson and .jsonl are commonly used. The extension does not change the contents.

The NDJSON specification requires UTF-8 text and a newline after each JSON value. It also states that JSON values must not contain literal newline or carriage-return characters. A line break inside a CSV field is safe only when it is encoded inside the JSON string as an escaped sequence such as \n.

Decide how values should be typed

CSV has no formal data types. It stores text arranged in rows and columns. JSON distinguishes strings, numbers, booleans, and null, so a converter has to choose between preserving the source text and inferring types.

Preserving values as strings is the cautious default:

{"postcode":"00124","active":"false","amount":"15.00"}

Aggressive type inference could turn that into:

{"postcode":124,"active":false,"amount":15}

The second object may be convenient for analysis, but it has changed the postcode and the original representation of the amount. Account numbers, phone numbers, product codes, and other identifiers should remain strings even when they contain only digits.

If the destination requires typed values, define the conversion rules explicitly. Do not infer a production schema from a few early rows.

Empty cell, empty string, or null?

These three states are not interchangeable:

  • a missing key means the field was not supplied;
  • "field":"" means the field was supplied as an empty string;
  • "field":null means the field is present with no value.

A blank CSV cell does not tell you which meaning was intended. Check the receiving system's contract before converting blanks to null or dropping their keys.

The same caution applies to placeholders such as N/A, NULL, -, and unknown. They are ordinary strings until you deliberately map them to something else.

Duplicate and empty headers need attention

JSON object keys should be unambiguous. A CSV like this is not:

name,email,email
Ada,ada@example.com,work@example.org

Many JSON parsers retain only the last duplicate key. Rename duplicate headers before conversion, for example to personal_email and work_email.

Blank headings create a similar problem. Run the CSV diagnostic first if the file came from an unfamiliar export or has already failed an import.

NDJSON is different from a JSON array

An ordinary JSON export often looks like this:

[
  {"order_id":"1001"},
  {"order_id":"1002"}
]

That is valid JSON, but it is not NDJSON. A line-oriented reader expects each line to be independently parseable. Conversely, a parser expecting one complete JSON document may reject an NDJSON file because it contains several top-level values.

Use CSV to JSON when the destination expects an array. Use NDJSON only when its documentation asks for NDJSON, JSON Lines, JSONL, or newline-delimited JSON.

Validate the output

Before sending a large file into a pipeline:

  1. Count the source data rows and output lines.
  2. Parse the first, middle, and last lines independently.
  3. Inspect identifiers with leading zeros.
  4. Check fields that contain quotes, commas, emoji, or line breaks.
  5. Confirm the required character encoding and maximum record size.
  6. Test a small batch against the real destination.

On systems with jq, this command parses each line and stops on malformed JSON:

jq -c . output.ndjson > /dev/null

To inspect the first record without loading the entire file:

head -n 1 output.ndjson | jq .

Converting NDJSON back to CSV

Use NDJSON to CSV when every record has a reasonably tabular shape. Nested objects and arrays require a policy: flatten them into columns, serialize them as JSON text, or move them into a related table.

No automatic choice is correct for every dataset. Inspect the result and confirm that a round trip has not collapsed nested data or changed missing values.

NDJSON is valuable because it preserves record boundaries while remaining easy to stream. A good conversion preserves those boundaries without quietly inventing a schema the source never had.

Use the CSV to NDJSON

Convert each CSV row into newline-delimited JSON for APIs, logs, BigQuery, and data pipelines. Your file is processed locally in the browser.