JSON to Parquet

How to convert JSON to Parquet in your browser

rows.page converts JSON or JSONL files up to 1.5 GB to zstd Parquet in your browser and flattens nested objects up to 8 levels deep, free with no signup. Drop the file and choose Parquet in the Export menu; to keep the nesting, use DuckDB or pandas.

.json.jsonl
Drop a file here
Stays in your browserUp to 1.5 GB

No file handy? Open Every country, as nested JSON (250 rows, 1.4 MB).

Convert JSON or JSONL to Parquet in rows.page

rows.page opens .json, .jsonl and .ndjson files. DuckDB-WASM reads the file inside your browser tab, so nothing is uploaded unless you press Share.

  1. Drop the file on rows.page, choose it from disk, or click Paste data and paste the JSON.
  2. Check the grid: nested objects show up as dot-path columns like user.address.city, and arrays stay list columns that show the first 6 items and "+N".
  3. Filter rows, hide columns or run SQL in the search box above the grid if you only need part of the data.
  4. Open the Export menu and choose Parquet. rows.page writes the file with zstd compression.

The export follows your current view: hidden columns are left out and a filtered view writes every matching row. A SQL result exports up to 1,000,000 rows.

How nested JSON maps to Parquet columns

The Parquet file from rows.page is flat. Each nested field becomes its own column named by its path, dots included, and the export writes those columns as they are:

  • {"user": {"address": {"city": "Utrecht"}}} becomes one column named user.address.city.
  • "tags": ["sql", "json"] stays a single list column and exports as a Parquet list, objects inside the list included.
  • Nesting below 8 levels, or an object with more than 200 fields, stays whole as one struct column.
  • A text column holding JSON objects is expanded into dot-path columns when 90% or more of its first 1,000 non-empty values are valid JSON objects.
  • A file that is one object wrapping a list, such as {"data": [...]}, opens as the rows of its biggest list (searched up to 4 levels deep), and a note says the other top-level fields were skipped.

Rename, cast or explode fields with SQL before exporting

Type a statement that starts with SELECT, WITH or FROM into the search box; the table is called data. Put dot-path names in double quotes, because DuckDB reads an unquoted user.address.city as a table called user and stops with an error.

sql
SELECT
  id,
  "user.address.city" AS city,
  CAST("order.total" AS DOUBLE) AS total,
  unnest(tags) AS tag
FROM data
WHERE "order.total" IS NOT NULL
ORDER BY __rid

unnest(tags) gives one row per array item, so a record with an empty tags array drops out of the result. ORDER BY __rid uses the hidden row-number column to keep the original file order. When the result looks right, export it as Parquet.

Compare JSON to Parquet conversion methods

JSON to Parquet conversion methods
MethodNested objects becomeInstall neededSize limit
rows.pageDot-path columns (8 levels, 200 fields per object); arrays stay listsNone, runs in the browser1.5 GB per tab
DuckDBSTRUCT columns; arrays become LIST columnsduckdb CLI or Python packageYour disk and memory
pandasSTRUCT columns; arrays become listspandas and pyarrowYour RAM; the whole file loads at once

Pick rows.page when a flat table is what you want. Use DuckDB or pandas when the Parquet file must keep its nested structure, or when the file is bigger than 1.5 GB: rows.page refuses a larger .json file and opens only the first rows of a larger JSONL file.

Convert JSON to Parquet with DuckDB or pandas

DuckDB

read_json reads both JSON arrays and JSONL, and COPY writes the Parquet file. Nested objects stay STRUCT columns and arrays stay LIST columns.

sql
COPY (SELECT * FROM read_json('in.json')) TO 'out.parquet' (FORMAT parquet, COMPRESSION zstd);

A glob such as read_json('logs/*.jsonl') combines many files into one Parquet file.

pandas

pandas writes Parquet through pyarrow, so install both. Pass lines=True for JSONL and leave it out for a JSON array; nested objects become STRUCT columns here too.

python
import pandas as pd

pd.read_json('in.jsonl', lines=True).to_parquet('out.parquet')

Check the Parquet file

Drop out.parquet back onto rows.page to check it. Parquet is not held to the 1.5 GB check because DuckDB reads it in place, and rows load in pages of 100 as you scroll.

The Columns panel shows each column's type, number of distinct values and share of nulls, plus a histogram with the value range for numbers and dates. For averages and medians, run FROM (SUMMARIZE data) in the search box. In DuckDB, DESCRIBE SELECT * FROM 'out.parquet' lists the columns and their types.

rows.page limits and prices

WhatLimit or price
Open a file in your browserFiles up to 1.5 GB, $0, no account, nothing uploaded
Share a link without an account$0, files up to 100 MB, link deleted 7 days after creation
Free account$0, 10 datasets kept, last 3 versions
Pro$12/month, 100 datasets, files up to 500 MB, private links
Max$39/month, 1,000 datasets, files up to 2 GB, private links

Questions

Why are my nested fields flat in the Parquet file?

rows.page flattens nested objects into dot-path columns such as user.address.city, up to 8 levels deep and 200 fields per object, and the Parquet export writes those columns as they are. To keep STRUCT columns, convert with DuckDB's COPY command instead.

How big a JSON file can I convert in the browser?

Up to 1.5 GB per tab. A bigger .json file is refused with "Too big for this browser", and a JSONL file over 1.5 GB opens only its first rows, so convert those with DuckDB.

Is my JSON uploaded during the conversion?

No. DuckDB-WASM reads the file and writes the Parquet export inside your browser, and nothing is uploaded unless you press Share.

How do I drop duplicate records before exporting?

Run SELECT DISTINCT * EXCLUDE (__rid) FROM data in the search box and export the result as Parquet. Leaving out the hidden __rid row number lets identical records match; SQL results export up to 1,000,000 rows.

Can I convert a JSON file from a URL?

Yes. Put the public URL after rows.page/, as in https://rows.page/https://example.com/data.json, then export as Parquet. If the host blocks cross-origin requests, rows.page fetches the file through its proxy (up to 100 MB, 30 seconds, 5 redirects).