Layerbit

JSON Formatter, Validator & Schema Tool

Validate, beautify, minify and repair JSON; query it with JSONPath; validate against or infer a JSON Schema; generate TypeScript, Go, C#, Kotlin, Python, Java or Rust types; export SQL and CSV — all client-side.

Raw JSON Input
Invalid JSON format.
Result

Everything a JSON document needs, in one place

Formatting is where JSON work starts, not where it ends. The same payload gets queried for one value, checked against a contract, turned into types for the code that consumes it, and loaded into a table. Each of those is a tab on the result pane, and each runs on the parsed document already in your browser.

Fix almost-JSON

Comments, trailing commas, single quotes, bare keys, NaN, Python's True/None, smart quotes from a document, a byte-order mark — the usual reasons a parser rejects something that is obviously meant as JSON. The Fix button rewrites exactly those and tells you what it changed, so you can judge whether the result is what the author meant.

JSONPath queries

Not just dotted paths: wildcards, recursive descent ($..id), negative indexes, slices, unions and filter expressions such as $.orders[?(@.total > 100 && @.status == "paid")]. Every match is listed with its full path, which is what you paste into the code that reads it.

JSON Schema, both ways

Paste a schema and validate the document against it with errors by path and keyword — type, required, enum, format, pattern, ranges, $ref, oneOf, if/then. Or infer a schema from the document: types, required keys, nullable fields, formats such as date-time and email, and enums for repeated string values.

Types for seven languages

TypeScript interfaces, Go structs with tags, C# classes with JsonPropertyName, Kotlin data classes, Python dataclasses, Java records and Rust serde structs — inferred from a sample, with optional fields where a key is sometimes missing and nullable types where a value is sometimes null.

SQL and CSV export

An array of objects becomes a CREATE TABLE with inferred column types and batched INSERTs for PostgreSQL, MySQL or SQLite, nested objects flattened into parent_child columns. Or a CSV with the same flattening, ready for a spreadsheet.

NDJSON and big documents

Log exports and streaming APIs produce one JSON object per line. Those are detected and parsed line by line, with per-line error reporting, and can be converted to an array or back. Documents of tens of megabytes format in well under a second; the tree view keeps them navigable.

Quick Testing Templates

Click a template to load it. The broken one shows the error position and the Fix button; the API response is the one to try Query, Schema, Types and SQL on.

What "valid JSON" actually means

JSON is specified by RFC 8259, and the grammar is deliberately tiny — six structural characters, four literals, strings, and numbers. That small surface is why it won, and it is also why so much of what people write is almost JSON. This validator uses the browser's native JSON.parse(), so what passes here is exactly what will pass in your runtime, not a looser approximation of it.

Trailing commas

{"a": 1,} is invalid. JavaScript object literals allow a trailing comma and JSON does not, which is why hand-edited config files break after someone deletes the last entry. This is the single most common parse failure, and the first thing Fix removes.

Single quotes

{'a': 1} is invalid. JSON strings must use double quotes, for both keys and values. Output copied from a Python repr() or a JavaScript console almost always needs this fixed.

Unquoted keys

{a: 1} is invalid. Every key is a string and must be quoted. JavaScript permits bare identifiers as keys; JSON never does.

Comments

Neither // nor /* */ is legal JSON. Formats that appear to allow them — tsconfig.json, VS Code settings — are JSON with Comments (JSONC), a different format parsed by a different reader.

NaN and Infinity

Not valid JSON values, despite being valid JavaScript numbers. A serialiser that emits them produces output no conforming parser will read — JSON.stringify converts them to null for exactly this reason.

Leading zeros and +

01, +1 and .5 are all invalid numbers. JSON requires 1, 1 and 0.5. Hex literals such as 0xFF are invalid too.

The precision problem nobody warns you about

JSON numbers have no specified size limit, but JavaScript parses them into IEEE 754 doubles, which hold integers exactly only up to 253 − 1. Beyond that, parsing silently loses precision:

This is why mature APIs serialise large identifiers as strings. If you control the producer, do the same. If you do not, parse with a library that supports BigInt rather than the native parser. This page scans the raw text for integers beyond that range and warns you above the input — the document is valid; the round trip through a double is what loses information.

Schema validation, briefly

A JSON Schema is a contract: it says which keys must exist, what type each value has, which strings are dates or emails, what a status field may contain. Validating a payload against it before you process it turns a vague runtime failure three functions deep into a precise message at the boundary — $.orders[2].total: expected number, got string. The validator here covers draft-07 and the 2020-12 keywords most schemas use: type, properties, required, additionalProperties, items, enum, const, format, pattern, numeric and length bounds, uniqueItems, local $ref, allOf/anyOf/oneOf/not, and if/then/else.

Inferring a schema from a sample is the fast way to get one. The inference marks a key as required only if every object in the sample has it, types a field as nullable only if a null was actually seen, and proposes an enum only when a string field repeats a small set of values. Treat the result as a draft: it describes the sample you gave it, not every document the producer might emit.

Minify, beautify, and what each is for

Both operations preserve the data exactly and change only the whitespace, but they serve opposite purposes. Beautifying is for reading, reviewing and diffing — a formatted file produces line-level diffs a human can review, whereas a minified one produces a single enormous changed line. Minifying strips every unnecessary byte for transmission and storage.

One caveat worth knowing: neither operation guarantees key order is meaningful. RFC 8259 defines an object as an unordered collection, so while JSON.parse and JSON.stringify happen to preserve insertion order in practice, you should never rely on ordering as data. If order matters, use an array. If you want a canonical form for comparison, enable Sort keys — or send both documents to the diff tool, whose structural mode ignores order entirely.

Why this runs in your browser

API responses are exactly the kind of thing that contains bearer tokens, customer email addresses, internal identifiers and occasionally a password reset link. Pasting that into a server-side formatter means handing it to infrastructure you cannot inspect. Everything here happens in the page: parsing, repair, queries, schema validation, type generation and SQL export are all local JavaScript. The indicator in the header counts network requests the page makes; it stays at zero while you work.

Frequently Asked Questions

Unlike server-side validation tools that transmit your pasted data across the internet, Layerbit executes all parsing and formatting locally within your machine using the browser's native JSON.parse() capabilities. Sensitive API keys, private user data and proprietary system configurations remain strictly on your device, and the header indicator shows the page has made no network request with your data.

It applies a fixed list of rewrites outside of string values: it removes comments and trailing commas, converts single and smart quotes to double quotes, quotes bare keys, replaces NaN, Infinity and undefined with null, converts Python's True, False and None, strips a byte-order mark, and inserts a comma between values that sit on consecutive lines without one. Each change is listed so you can review it. It never guesses at missing brackets or reorders data; if the result still does not parse, the error position tells you what is left.

The root $, dotted keys, bracket keys with quotes for names containing spaces, numeric and negative indexes, wildcards with [*] or .*, recursive descent with .., slices such as [0:5], unions such as [0,2] or ['a','b'], .length on arrays and strings, and filters written as [?(@.price > 10 && @.status == 'paid')] with ==, !=, <, >, <=, >=, regex matching via =~ /pattern/, negation and parentheses. Every match is returned with its exact path.

type (including integer and type arrays), properties, patternProperties, additionalProperties, propertyNames, required, dependentRequired, minProperties and maxProperties, items and prefixItems, contains, minItems, maxItems and uniqueItems, enum and const, minimum, maximum, exclusiveMinimum, exclusiveMaximum and multipleOf, minLength, maxLength, pattern and format (date-time, date, time, email, uri, uuid, ipv4, ipv6, hostname, regex), local $ref to definitions or $defs, allOf, anyOf, oneOf and not, and if, then and else. Remote $ref URLs are not fetched, because nothing on this page makes network requests.

The generator walks every object in the sample. A key present in some objects of the same shape but not others becomes optional (a ? in TypeScript, omitempty in Go, Optional in Python). A value that is null in at least one place becomes nullable. A field that is sometimes an integer and sometimes a decimal becomes a floating-point type. Arrays merge the shapes of all their elements. Give it a representative sample with a few records rather than one, and the result reflects the real variation.

Each column's values are examined across every row: all integers gives BIGINT (INTEGER in SQLite), any decimal gives DOUBLE PRECISION, booleans give BOOLEAN or TINYINT(1), ISO date strings give TIMESTAMP or DATETIME, and everything else gives TEXT or a VARCHAR sized from the longest value. A column with no nulls is marked NOT NULL. Nested objects are flattened into parent_child columns and arrays are stored as JSON text. Identifiers are converted to snake_case and quoted for the chosen dialect.

The Tree view renders the same parsed payload as a collapsible outline, letting you fold entire objects or arrays down to a single line and expand only the branches you need. This is especially useful for deeply nested API responses, where the plain formatted text can run to thousands of lines. Use Expand All or Collapse All to jump between a full overview and a fully drilled-in view.

Changelog