DEV Community

AI Dev Hub
AI Dev Hub

Posted on

Reading 50MB JSONL logs with a viewer in 2026

Reading 50MB JSONL logs with a viewer in 2026

Use a browser-based JSONL viewer that parses each line as its own JSON object and lays the results out in a filterable, sortable table. That's the fastest way to read newline-delimited logs without writing a throwaway script. Paste the file, get columns, filter to the rows you care about, export what's left. No terminal gymnastics and no 2GB file crashing your editor. Works offline because everything runs client-side.

The jsonl viewer I link to below is one I built. I got tired of it: I tried six different online JSON tools last spring and every one of them choked the moment I pasted newline-delimited data, because they all assume a single JSON document and JSONL is a stream of them. Mine runs entirely in your browser. No signup, no upload, nothing leaves your machine, and it's free. If you've got a better one, please tell me.

The log file that killed my text editor

Last Tuesday, around 2am, I was chasing a production timeout. The only evidence I had was an NDJSON log the service had been streaming to disk: 340 MB, roughly 1.2 million lines, one JSON object per line. I did the obvious thing first and opened it in my editor. It thought about that for a while. The fans spun up. Then the window went white and stopped responding. Cool.

So I fell back to jq. jq 'select(.level == "error")' app.log does work, and honestly jq is a wonderful tool, but I couldn't remember the exact field names, I kept getting the filter slightly wrong, and every failed guess re-streamed the whole file from the top. Twenty minutes in I still hadn't seen a single row. The error turned out to be on line 811,406, but I didn't know that yet. All I wanted was to see the shape of the data first, then decide what to filter. That's the gap.

JSONL (also called NDJSON or JSON Lines, same idea under different names) is a stream of JSON values with one per line. Log pipelines love it because you can append a line without rewriting the file, and a crash mid-write only costs you the last line instead of the whole document. The catch is that most JSON tooling assumes a single document, so it reads your 1.2 million lines and immediately throws on the second {.

How a JSONL viewer parses a stream of objects

The core of a JSONL viewer is almost embarrassingly small. You split on newlines and parse each non-blank line on its own. The one trick that matters is not letting a single bad line kill the whole render, so you catch per line and keep going.

// Split, drop blanks, parse each line independently.
function parseJSONL(text) {
  return text
    .split('\n')
    .filter((line) => line.trim() !== '')
    .map((line, i) => {
      try {
        return { ok: true, row: JSON.parse(line) };
      } catch (err) {
        return { ok: false, line: i + 1, raw: line, error: err.message };
      }
    });
}

const sample = `{"ts":"2026-04-11T02:14:03Z","level":"error","msg":"timeout","ms":9812}
{"ts":"2026-04-11T02:14:04Z","level":"info","msg":"retry","attempt":2}
not valid json
{"ts":"2026-04-11T02:14:06Z","level":"info","msg":"ok"}`;

console.log(parseJSONL(sample));
Enter fullscreen mode Exit fullscreen mode

Run that and you get four results back. Three parse cleanly into row objects, and the not valid json line comes back as { ok: false, line: 3, ... } instead of blowing up the other three. A viewer takes that array, unions all the keys it sees to build columns (ts, level, msg, ms, attempt), and paints a table. Now level is a column you can filter, not a string you have to grep for.

You don't have to run this yourself. Paste your file into the JSONL viewer and it does exactly this in your browser, then hands you a sortable, filterable table with the broken lines flagged in red so you can spot corruption instead of silently dropping it. That red-flag behavior is the part I use most, weirdly. Half my "bug" reports turn out to be one truncated log line.

What the table actually gets you

Parsing is the boring half. The reason a table beats a wall of text is what you can do to it once it's there. I filter first, almost always. Type error into the level column and 1.2 million rows collapse to the 3,000 that matter. Then I sort by timestamp to find the first one, because the first error is usually the real cause and the rest are fallout.

Sorting on a numeric field (say a duration in ms) is where the table earns its keep. In an editor I'd be eyeballing numbers by hand. Here I click the ms header and the slowest request floats to the top. Last week that surfaced a single 14,203 ms outlier I'd never have spotted by scrolling, and it was the whole bug.

Export closes the loop. Once I've filtered down to the rows I care about, I pull them out as JSON or CSV and drop that slice into a ticket, so the person picking it up sees 40 relevant lines instead of a 340 MB file and a shrug.

jq versus a spreadsheet versus a text editor

Each of these has a place. Here's how I actually pick between them:

Approach Reads JSONL as-is Live filtering Big files Setup cost
Browser JSONL viewer Yes Yes, instant Fine to ~100 MB None, it's a web page
jq on the CLI Yes No, re-run per query Excellent, it streams Install plus learn the syntax
Import into a spreadsheet No, needs flattening Yes Poor past a few MB Manual conversion step
Text editor plus grep No Text search only Bad, loads it all Already open

The viewer wins when I'm exploring and don't yet know what I'm looking for. jq wins when I know the exact query and want it in a script or a pipe. I reach for jq inside CI, and the viewer at 2am when my brain is half offline. Different jobs, and I stopped feeling guilty about using both.

When you shouldn't reach for it

I built this thing and I still won't use it for everything. A few honest limits.

If your file is genuinely huge (multiple gigabytes), keep it in jq or a streaming parser. A browser tab has a memory ceiling, and loading 3 GB into a table will hang the page the same way it hung my editor. The viewer is for the range where an editor struggles but the data still fits in RAM, so call it a few hundred MB and under.

If the task is automated, a viewer is the wrong shape entirely. Anything that runs on a schedule or inside a build should be jq or a small script. A human clicking a web page doesn't belong in a cron job, and you'll hate maintaining it if you try.

And if you're dealing with deeply nested objects, a flat table gets awkward fast. The viewer flattens what it can and shows nested blobs as collapsed JSON, which is readable but not magic. For heavy nesting I still drop back to jq's path expressions. No tool wins every round, and pretending otherwise is how you end up with the wrong one open at 2am.

FAQ

Q: Is JSONL the same thing as NDJSON?
A: Effectively yes. JSONL, NDJSON, and JSON Lines all name the same format: one JSON value per line, separated by \n. There are pedantic edge cases around trailing newlines and empty lines, but any decent viewer handles the three names identically.

Q: Does my data get uploaded anywhere?
A: No. The parsing runs client-side in your browser, so the file never leaves your machine. That was the entire reason I built it that way. I didn't want to paste production logs into someone else's server and hope for the best.

Q: How big a file can it actually handle?
A: It depends on your available RAM more than anything else. I've thrown 90 MB files at it without trouble on a normal laptop. Past a few hundred MB you'll feel the tab get heavy, and that's your cue to switch to jq.

Q: Can I export the filtered rows?
A: Yes. Once you've narrowed down to the rows you want, you can export just the visible set as JSON or CSV, which is handy for handing a teammate a clean slice instead of the raw dump.

Q: Why not just use jq for all of it?
A: You can, and plenty of people do. I like jq for known queries and pipelines. The viewer is for the messier moment before that, when I don't yet know the field names or what I'm even looking for and want to poke at the data with my eyes.

Written with AI assistance and human review. Try the tool at aidevhub.io/jsonl-viewer.

Top comments (0)