GeoJSON to NDJSON
One feature per line. Newline-delimited GeoJSON streams, greps, splits and loads into BigQuery, DuckDB, and line-oriented pipelines — none of which want a single 400 MB array they have to parse whole.
GeoJSON to NDJSON
What this tool does
It takes a FeatureCollection and writes each feature as one minified JSON object on its own line. Nothing is lost — properties, ids and geometries are all preserved — but the wrapping array disappears, and with it the need to hold the whole file in memory to read one record.
The intent it closes: "this file is too big to parse in one go, or the loader wants one JSON object per line." BigQuery, Athena, DuckDB, Spark, jq -c, split, and grep all work naturally on this shape. It is also the format the sibling site jsonlkit.com is built around.
How this tool works
A flat rewrite, with one optional wrinkle.
1. Collect the features
The input is normalised first: a FeatureCollection gives its features, a single Feature gives one line, and a bare geometry is wrapped in a feature so the output shape stays consistent. Top-level members of the collection — bbox, name, anything foreign — are not carried over, because there is no line for them to live on.
2. Write one line per record
Each feature is serialised with JSON.stringify and no indentation, so a line contains no newlines and the file is safely splittable. With Each line is a bare geometry, only the geometry object is written and properties are dropped — smaller, and the right choice when the consumer only cares about shapes.
3. Optionally add record separators
RFC 8142 defines GeoJSON Text Sequences: each record is preceded by an ASCII record separator (0x1E) and followed by a newline. That form is what the application/geo+json-seq media type describes, and some streaming parsers require it. Plain NDJSON — no separators — is what most data warehouses expect.
Options
Each line is
A Feature keeps everything and is the interchangeable form. A bare geometry drops properties entirely, which halves the size of a geometry-heavy file and suits a pipeline that joins attributes from elsewhere.
RFC 8142 record separators
Leave it off for BigQuery, DuckDB, jq and friends — an unexpected 0x1E byte breaks them. Turn it on only when a consumer explicitly asks for geo+json-seq.
Example
Input:
{"type":"FeatureCollection","features":[
{"type":"Feature","properties":{"n":1},"geometry":{"type":"Point","coordinates":[0,0]}},
{"type":"Feature","properties":{"n":2},"geometry":{"type":"Point","coordinates":[1,1]}}
]}
Output:
{"type":"Feature","properties":{"n":1},"geometry":{"type":"Point","coordinates":[0,0]}}
{"type":"Feature","properties":{"n":2},"geometry":{"type":"Point","coordinates":[1,1]}}
Two lines, each a complete GeoJSON Feature. You can now head, split, or stream the file, and a truncated download still yields whole records up to the break.
Tips & common pitfalls
- Use the extension your tool expects.
.geojsonl,.ndgeojson, and.jsonlall appear in the wild; BigQuery wants newline-delimited JSON regardless of the name. - Collection-level members are dropped. A top-level
bboxorcrshas nowhere to go. Recompute the bbox after reassembling if you need it. - It is not compression. The bytes are roughly the same as a minified collection; the win is streamability and splittability, not size. Combine with precision for actual size reduction.
- Round-trips cleanly. NDJSON to GeoJSON puts the collection back together, so this is a safe intermediate step.
FAQ
What is the difference from a minified FeatureCollection?
A minified collection is one JSON value: a parser must read all of it before it can hand you the first feature. NDJSON is many values, one per line, so a reader can process feature 1 without seeing feature 2 — and you can split the file anywhere.
Which format does BigQuery want?
Plain newline-delimited JSON with no record separators. Leave the RFC 8142 option off, and consider the bare-geometry mode if you are loading into a dedicated geography column.
Are the lines valid GeoJSON on their own?
Yes — each line is a complete Feature (or geometry), which is a valid GeoJSON object in its own right.
Is my file uploaded?
No. The conversion happens in the browser.