✳ OMNIVIEWER

Drop a JSON Lines file. Any size.

safe · secure · no server · works offline · fast

…or just start typing at the cursor.

Or try it now

↓ scroll for about & FAQ

View, validate and convert JSON Lines online — without uploading it

OmniViewer opens a JSON Lines file right in your browser. Drop a .jsonl or .ndjson file and you get a record browser with every record validated, an inferred schema, and one-click conversion to CSV or a JSON array. There is no upload and no server — the file is read directly by your browser, and the scan runs in a background Web Worker so the page never freezes.

JSON Lines is one complete JSON value per line — the format every log pipeline, analytics export, LLM fine-tuning set and BigQuery/Athena/DuckDB dump uses. That is also why JSON.parse(file) fails on it and why most JSON viewers show you an error instead of your data: the file is not one document, it is millions of them.

What each tab does, in plain terms

Find the one broken record in forty million

This is what the route is for. A JSONL export is produced by a pipeline and consumed by a loader, and when the loader stops it says something like invalid JSON on line 12,000,412 — with no way to look at line 12,000,412. OmniViewer reads every byte of the file, however large, and reports each broken record with its record number, its byte offset and the parse error, then opens it on one click. The three failures it finds most often are a truncated final line (a killed process, a lost multipart upload), a trailing comma left over from thinking in arrays, and a pretty‑printed JSON document saved with a .jsonl extension — which the viewer detects by name rather than reporting 400,000 identical errors.

How we read a 20 GB .jsonl file

JSON Lines is the one JSON dialect where a record boundary is a byte, not a parser state: a record ends at the next newline, and 0x0A cannot appear inside a UTF‑8 multi‑byte sequence or inside a JSON string. So the whole file can be split with a plain byte scan, in 4 MB blocks, carrying only the partial trailing record across a block edge — peak memory is one block plus the field table, whatever the file weighs. That is why the record count, the broken‑record list and the schema cover the entire file rather than a sample. The two conversions (CSV and JSON array) have to produce one document, so they work on a bounded prefix and say so. For the full story with real code, read what is a .jsonl file? JSON Lines and NDJSON explained.

Where JSON Lines came from

The format has no single inventor and no RFC — it was reinvented independently wherever someone needed to put JSON in a pipe, which is why it has four names for the same bytes: JSON Lines (.jsonl, the spelling of jsonlines.org and the common one today), NDJSON (“newline‑delimited JSON”, the name the streaming ecosystem uses), LDJSON (“line‑delimited”, older, from logging stacks) and loosely “JSON stream”. Its rise came with big‑data tooling in the 2010s: Hadoop, Spark, Athena and BigQuery all want to hand byte range k of a file to worker k, and only a line‑delimited format lets them find a record boundary without a parser. MIME types you will meet are application/x-ndjson and application/jsonl; neither is registered with IANA. Do not confuse any of it with JSON Text Sequences (RFC 7464), which separates records with a 0x1E byte instead of a newline.

A tiny example of JSON Lines:

{"id":1,"name":"Ada","tags":["admin"]}
{"id":2,"name":"Bob"}
{"id":3,"name":"Cy","tags":[]}

How JSON Lines compares to JSON, CSV and Parquet

AspectJSON LinesJSONCSVParquet
ShapeOne value per lineOne nested documentFlat rowsColumnar, binary
Nested dataYes, per recordYesNoYes
SchemaNone — implicit, per recordNoneHeader row, untypedTyped, in the footer
AppendableYes, one line at a timeNoYesNo
Split without parsingYes, at any newlineNoUsuallyBy row group
Streaming read memoryOne recordWhole documentOne rowOne column chunk
Survives truncationYes — lose the last recordNoYesNo
Typical useLogs, exports, training setsAPIs & configSpreadsheetsAnalytics storage

OmniViewer opens every file format; JSON Lines is one of the formats with dedicated tooling, alongside JSON, CSV and Parquet — powered by the same viewing engine as fastjsonviewer.com and hugecsv.com.

FAQ

Is my .jsonl file uploaded anywhere?

No. OmniViewer is a static page with no server-side processing: your .jsonl or .ndjson file is read directly by your browser, and every tab — records, schema, CSV, JSON and stats — runs locally in a Web Worker. The file never leaves your computer.

What is a .jsonl file, and how is it different from .json?

A .jsonl file is JSON Lines: one complete JSON value per line, separated by newlines, with no wrapping array and no commas between records. A .json file is a single document. That is why JSON.parse on a whole .jsonl file fails at the start of the second record — it finished a complete value and then found more content. Each individual line, however, is perfectly valid JSON.

Are .jsonl and .ndjson the same thing?

Yes. JSON Lines (.jsonl), NDJSON (newline-delimited JSON, .ndjson) and LDJSON (line-delimited JSON, .ldjson) all describe the same bytes: one JSON value per line. OmniViewer treats them as one toolkit, so a .ndjson file opens on the same route with the same tabs. JSON Text Sequences (RFC 7464) is genuinely different — it separates records with a 0x1E byte, not a newline.

How large a JSON Lines file can I open?

Effectively unlimited, up to 20 GB and beyond; the engine behind the raw and hex views has been tested in-browser with a 40 GB file. The record scan is the same: because a record boundary in JSON Lines is a single newline byte, the whole file is streamed in 4 MB blocks and only the partial trailing record is carried across a block edge, so the record count, the broken-record list and the schema cover every byte. The CSV and JSON-array conversions produce one document, so those work on a bounded prefix and tell you when they do.

Can OmniViewer find the broken record in a large export?

Yes — that is the point of the route. Every record in the file is parsed, and each one that fails is listed with its record number, the byte offset it starts at and the parse error, wherever it sits in the file. Click it to open the record itself. If the whole file turns out to be a pretty-printed JSON document saved with a .jsonl extension, the viewer says so by name instead of reporting one error per line.

Can I convert JSON Lines to CSV or to a JSON array?

Yes, both. The CSV tab flattens each record to one row, turning nested objects into dotted column names and keeping arrays as JSON in a single cell; columns are the union of every record’s fields, so a record missing one gets an empty cell. The JSON tab wraps the records into one pretty-printed JSON array. Both are ready to copy or download, and both work on a bounded prefix of a very large file and say so.

What does the schema tab tell me that the records tab does not?

JSON Lines has no schema, so nothing in the file guarantees that every record has the same fields or the same types. The schema tab walks every record and reports each field path with the share of records that carry it and the mix of types it was seen with. That is where you discover that user.email is in a quarter of your records, or that qty is a number in most of them and a string in a few — the reason a strict load into BigQuery, a typed struct or a Parquet writer rejects an export that parsed perfectly.

Does it handle CRLF line endings, blank lines and a byte-order mark?

Yes. A trailing carriage return is whitespace as far as JSON is concerned, so CRLF files read the same as LF ones. Blank lines are not records: they are skipped and counted separately in stats. A UTF-8 byte-order mark is treated as belonging to the file rather than to the first record, so it never turns record 1 into a parse error.