Convert TOML to NDJSON

Converting TOML to NDJSON writes the whole configuration as one compact JSON line, because a TOML document is a single table and newline-delimited JSON splits on a top-level list. For the job people usually bring to this pair — turning a directory of config files into a queryable dataset — one file per line is exactly the right unit.

  • Where it runs In your browser. The file is never uploaded.
  • Lossless Nothing is discarded. The NDJSON holds exactly what the TOML held.
  • File size limit Up to 100 MB per file, free, without an account.

Up to 100 files at once. Mixed formats are fine.

One config file, one line, and why that is the right unit

A TOML document is a table. There is no such thing as a TOML file that is a list at the top level — the specification does not allow it — so the record boundary that newline-delimited JSON needs never appears inside a single file. The whole document becomes one line.

For most sources that would be a limitation. Here it is the shape of the problem: nobody wants a pyproject.toml split into fragments, and everybody who converts one to NDJSON is building a collection where each file is a record. The unit of the format and the unit of the question happen to agree, which is not true of every pair on this site.

Building an inventory of every Cargo.toml in a workspace

The workflow is: convert each file, append the line to a growing output. Because every line is a complete, self-contained JSON value and nothing wraps the file — no enclosing array, no commas between records — concatenation is the entire merge step. Two lines from two conversions are a valid two-record NDJSON file.

What that gets you is a dataset you can ask questions of. Which crates pin a specific dependency version, which packages declare no licence, which repositories still target an old edition — all of them are one query over the collection instead of a script that walks directories and parses files. Building that inventory is much more useful than reading any single config, and it is the reason this pair exists.

The field the conversion cannot add for you

A record with no source is close to useless in an inventory. The converter reads the contents of a file and nothing else — it does not know the path, the repository or the commit — so the line it produces has no field saying where it came from.

Add it yourself, at one of two moments. A jq pass during concatenation can inject a path key per line, which keeps the TOML files untouched and is the right approach for a fleet you do not own. Alternatively, a key inside each TOML file names it, which survives every future conversion but means editing files that belong to other people. The first scales; the second is more honest when the file really should identify itself.

What one line contains

Compact JSON: no indentation, no spaces after colons, keys in the order the TOML declared them, ending with a newline. Tables become nested objects and arrays of tables become arrays of objects, so an authors list or a set of build targets arrives in the shape a query engine expects.

The line is as long as the config is. A pyproject.toml is a few kilobytes and a generated lock-adjacent config can be far larger, and a reader that processes a line at a time has to hold the whole line in memory. That is rarely a problem at config sizes, and it is worth knowing before somebody points this at a file that is not really a config.

Typed values crossing into a stream

TOML has real temporal types and JSON does not, so every date and datetime becomes a string. Offsets survive rather than being normalised to UTC, a local date arrives exactly as written, and a local time gains a millisecond component it did not have in the source. Most loaders will read those as text unless the target schema says otherwise.

Two float literals are lossy in a way nothing reports: inf and nan are valid TOML and become null in JSON, so a configured infinite limit and an unconfigured one become indistinguishable in the dataset. The integer-float distinction goes as well, since 1.0 serialises as 1 — which matters if a query is meant to tell a version from a count.

The TOML file that stops the conversion

TOML 1.0 requires 64-bit signed integers and JSON numbers are IEEE doubles, so a value above roughly nine quadrillion cannot be represented exactly. The parser stops with an error naming the line rather than writing a rounded number into your dataset.

That is the correct behaviour for an inventory in particular, where a wrong number would be indistinguishable from a right one across ten thousand records. When it happens, quote the value as a string in the source file — it was an identifier rather than a quantity in every real case where this comes up.

Records that do not share the same keys

Configs from different projects will not have the same sections. One declares a tool table with three linters in it, the next declares none, a third uses a key nobody else uses. Every line carries only the keys its file had, which is a real advantage over flattening the same collection into a table where the columns would have to be the union of everything.

The destination decides how much that costs. A schema-on-read store handles ragged records natively and lets a query ask for a key that only some records carry. A loader with a fixed schema will reject the outliers or drop the fields. Sample the widest and the narrowest files in the collection before defining the target, rather than after loading eight thousand records.

Comments, and what the dataset is missing

TOML comments are the reasoning in a config: why a dependency is pinned, which ticket a workaround belongs to, what a magic number means. NDJSON is JSON per line and JSON has no comment syntax, so all of it is gone from the dataset.

That is acceptable for an inventory and not acceptable as a migration. Nobody querying which packages pin a version needs the surrounding prose; anybody replacing the TOML files with something generated from this data would be throwing it away. Use the stream to answer questions about the configs, and leave the configs where they are.

When a single JSON file is the better answer

If you only have one config to read, convert it to JSON instead. Indented JSON is readable, jq handles it identically, and a one-line file is worse for every purpose except appending. NDJSON earns its place at the point where there are many files and they are going into something.

The other boundary is recurrence. If the inventory has to be rebuilt on a schedule, the work belongs in a script that walks the tree, parses each file with a real TOML library and emits the lines with the path already attached. This converter is for building the dataset the first time, deciding whether the questions it answers are worth automating, and doing it without any of the files leaving your machine.

How to convert TOML to NDJSON

  1. Drop your TOML file onto this page, or click to choose one.
  2. It is written as one compact JSON line in your browser.
  3. Download the line and append it to your dataset.

TOML against NDJSON: one config against one line of a stream

TOML compared with NDJSON
TOMLNDJSON
Full nameTom's Obvious Minimal LanguageNewline-Delimited JSON
File extension.toml.ndjson, .jsonl
Media typeapplication/tomlapplication/x-ndjson
First published20132013
SpecificationTOML 1.0
LicensingOpen standardOpen standard
Standing todayCurrentCurrent
Opens in a browserNo browserNo browser
Considered insteadYAML, JSON, INIJSON, CSV

What is lost

Comments do not survive. TOML lets you annotate a file and NDJSON has no syntax for it, so every explanatory line is dropped — which matters most on exactly the files people comment: configuration somebody else has to maintain.

What survives

Nothing is discarded. TOML and NDJSON both store their content losslessly, so the conversion is a change of packaging rather than a change of quality, and it can be repeated without accumulating damage.

Opening the result

The usual programs do not overlap: TOML opens in Visual Studio Code, NDJSON in jq and pandas — so whoever receives the result needs something from the second list.

What each format is for

The two are aimed at different work: TOML at editing, NDJSON at moving data between programs and streaming. That is worth weighing before converting, because the reason one exists is usually the reason the other is awkward.

TOML was published in 2013. The specification is TOML 1.0, and it is worth reading if the file has to outlive the tool that wrote it.

NDJSON dates from 2013. jq and pandas all read it.

TOML to NDJSON: questions about building a config dataset

Are my TOML files uploaded anywhere?

No. This conversion runs entirely inside your browser, so the file never leaves your device. You can confirm it yourself: open the network tab of your browser's developer tools and convert something. You will see the page load, plus the analytics and advertising the site is paid for with — and nothing carrying your file.

Why is the output only one line?

Because a TOML document is a table, and a table is one value. Newline-delimited JSON splits on a top-level list, and TOML has no top-level list to split on. For this pair that is the intended result: one config file becomes one record.

How do I build a dataset from many files?

Convert each file and append the lines to one file. Because every line is a complete JSON value and nothing wraps them, concatenation is all the merging that newline-delimited JSON needs.

Does the record say which file it came from?

No. The conversion sees the contents and not the path, so a source field has to be added — by a jq pass at concatenation time, or by adding a key to each TOML file before converting.

What happens to TOML datetimes?

They become strings, since JSON has no date type. Offsets are preserved, local dates come across as written, and a local time gains a millisecond component. Most loaders will need a schema hint to read them as timestamps.

Why did a file fail to convert?

Most likely a very large integer. TOML requires 64-bit integers and JSON numbers cannot hold them exactly, so the parser stops rather than rounding. Quote that value as a string in the TOML.

Are the files uploaded?

No. Parsing and writing both happen in this page in JavaScript, so config files with tokens or internal registry URLs in them stay on your machine.

More about these formats