JSON Editor
Edit JSON in a tree, table or text view — every change re-renders the other two and big numbers stay exact, entirely on this device.
Paste JSON, drop a file, or Load sample
Paste an array of objects to edit it as a grid.
Press ? for shortcuts
Do it offline:$ jq '.items[0].qty = 5' data.json
How to use it
- Bring a document in by pasting it, dropping a .json file on the pane, or loading the sample. Below 64 KB it parses on every keystroke; past 2 MB a button states the size before any work starts, and ⌘/Ctrl + Enter runs it on demand.
- Choose Tree, Text or Table from the segmented control. Tree suits nesting and single-value edits, Text is the raw source for bulk changes, and Table lays an array of objects out as a grid. Switching views rewrites nothing — each one redraws from the same current text.
- Edit in whichever view fits. In the tree, open a row to change its value, rename its key, change its type, or add and delete entries; in the table, tab across cells and edit them in place; in text, type freely and the tree and table catch up the next time it parses.
- Copy the result or download it as a .json file, and Share folds the whole document and your current view into a link. Undo and redo cover every value and structural change, so nothing you try is one-way.
Paste JSON, then change it in place: rename a key, retype a value, add or drop a field, or work a whole array of objects as a spreadsheet. Every edit is written straight back into your own text as a precise byte-level splice, so the parts you did not touch stay exactly as they arrived — same key order, same spacing, same long numbers. Tree, Text and Table are three views of that one document.
How it works
A JSON document, in RFC 8259, is one value assembled from six building blocks: object, array, string, number, boolean and null. This page keeps your document as a single thing — the source text you pasted — and parses it once into a compact index that notes each value's type, how deep it sits, and the precise slice of characters it spans. No JavaScript object graph is built from your data; the index points into the bytes rather than copying them out.
When you change a value in the tree or a cell in the table, the page does not re-print the document. It replaces just the characters between that value's start and end offsets with the new ones and leaves every other byte alone. Retyping a number edits its digits and nothing else; deleting an entry removes its span and repairs the single comma that would otherwise dangle. Because the surrounding text is never regenerated, key order and whitespace survive an edit untouched.
Tree, Text and Table are not three copies racing to stay in sync; they are three renderings of the same source text. The table takes an array of objects and lines their keys up as columns, so a list of records reads and edits like a spreadsheet. Switching views re-derives the target from the current text, and a tree or table edit produces new text the others read next, so the three never disagree. Each value also has an address — a path in the sense of RFC 9535 — that the editor uses to announce to a screen reader exactly which value an edit changed.
This is why large numbers come through an edit intact. A value you never touched is never parsed into a float — it stays the exact digits in the source — and a value you retype is spliced in exactly as written, digit for digit. The identifier 9223372036854775807 keeps all nineteen digits here even after you edit the field beside it, whereas running JSON.parse over the saved result answers 9223372036854776000. Copy and Download hand you the same characters, so the number that leaves is the number you saw.
Examples
{"items":[{"sku":"KB-701","qty":2}]}{"items":[{"sku":"KB-701","qty":5}]}The qty cell held 2; typing 5 rewrites one character. Everything around it — the items array, the sku string, every brace — is byte-for-byte what it was, because the edit is a splice at that value's range, not a re-print.
{"id":9223372036854775807,"n":1}{"id":9223372036854775807,"n":2}Here the edit is to n, sitting right next to a 64-bit id. The id is outside the edited range, so it is never turned into a number — its nineteen digits are the same bytes before and after. Feed the saved document to JSON.parse and the id reads back as 9223372036854776000.
[{"sku":"KB-701","qty":2},{"sku":"MS-220","qty":1,"note":"backorder"}]sku | qty | note
"KB-701" | 2 | —
"MS-220" | 1 | "backorder"Two records with different fields become one grid: the columns are the union of every key in first-seen order, and the row that carries no note field shows an em-dash — the field is absent, not empty. The editor states that rule out loud, because absent and empty write back as different documents.
{
"host": "db-1",
"port": 5432
}{
"host": "db-1",
"port": 5432,
"ssl": true
}Adding ssl with the value true keeps the document's own shape: the page read two-space indentation off the existing lines and copied the comma-and-newline the other fields use, so the new line lands formatted like its neighbours. An empty object has no sibling to copy, so it opens to a single indented line instead.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
Blank table cells mean absent, not empty
When an array's objects carry different keys, the table shows the union of all of them and marks the cells a given row lacks with an em-dash. That mark is neither an empty string nor null — it means the key is simply not in that record. Typing a value there adds the field rather than filling a blank.
A table needs objects for its rows
The table view expects an array of objects, one record per row. When some elements are numbers, strings or arrays instead, the grid still renders and a note counts how many rows are not objects; those you edit in the tree or text view, where a bare value has somewhere to live.
Object and array cells preview, then open in the tree
A cell whose value is itself an object or an array cannot be typed into a grid square, so the table shows a short preview and points you to the tree, where nested structure has room to expand. The cell still knows precisely which node it is, so the drill-in lands on the right value.
The editor will not create a duplicate key
Renaming a key to one a sibling already uses, or adding a field whose name is taken, is refused with a message that names the collision. An object can technically repeat a key — the tree will show you one that did — but minting duplicates would hand you a document whose meaning depends on which parser reads it.
Changing a value's type is one splice
Turning a string into a number, or a value into null, an object or an array, swaps the whole value token for a literal of the new type: typing 5 over the string "5" yields the number 5, and typing null yields null. If what you type is not valid JSON the edit is declined and the old value stays put.
64-bit identifiers survive an edit
Snowflake ids, sequence numbers and cent-precise money totals routinely pass 2⁵³, where IEEE 754 doubles begin to round. Values you edit are spliced in as the exact characters you type, and values you leave alone are never parsed, so a database id keeps every digit.
Past 50 MB the whole file is refused
Below the cap, parsing and editing run on this device, moving to a background thread as the document grows. Above 50 MB the page declines the file whole rather than loading a slice, since editing the first 50 MB and saving would silently drop the rest. The banner names the limit and a command-line alternative.
Common errors
Input is larger than the 50 MB limit for this tool. For bigger payloads use the CLI: jq . file.json | less- The editor refuses an oversized document outright instead of loading part of it — a partial load you then saved would quietly lose everything past the cut. Your paste is left exactly where it is, and that command runs locally, streaming a file of any size as privately as this page.
Edited value is not valid JSON. Unexpected 'a' at line 1, column 2 — probable cause: property names must be double-quoted.- The first line is the editor; the second is the same parser that validates the whole document, run on just the value you typed. Here {a:1} is a JavaScript object literal, not JSON — its key needs quotes. Until the value parses as one well-formed JSON value the edit is declined and the document is left as it was.
An entry named "port" already exists in this object.- You tried to add or rename a field to a name a sibling already holds. The editor names the clash and makes no change, because two entries called port in one object is exactly the ambiguity a JSON editor should not manufacture. Rename the existing field first, or edit its value in place rather than adding a second one.
FAQ
How is this different from the JSON Tree Viewer?
The viewer is read-only on purpose: it promises that what you see is exactly what arrived, so it never writes to your text. This page writes — the same source-preserving display, with editing on top, handing back a document you can copy or download.
Will editing reformat or reorder the rest of my file?
No. An edit rewrites only the value or key you changed, a splice into that exact range, with the bytes on either side copied through untouched. Adding a field or item is the one exception: the new entry adopts the indentation and separators already in use.
Do big numbers stay exact when I edit nearby fields?
Yes. Numbers you do not edit are never parsed into floating point — they stay the literal digits in your source — and numbers you type are spliced in character for character. A 64-bit id keeps every digit even after you change the value beside it, which no tool that edits through JSON.parse can promise.
How do the Tree, Text and Table views stay in agreement?
There is only ever one document — the source text — and every view is drawn from it. An edit produces new text, and switching views rebuilds from that same text. Nothing is duplicated, so there is no second copy to fall out of step.
Can I edit an array of objects like a spreadsheet?
That is what the Table view is for: an array whose elements are objects becomes a grid of columns, one record per row, edited cell by cell. Records with different keys share a union of columns; elements that are not objects, and cells holding nested structure, are flagged and edited in the tree instead.
Does anything I edit get uploaded?
No. Parsing, every edit and each export happen inside this browser tab, and a dropped file is read locally — watch the network panel stay silent while you work. A share link keeps the document in the URL fragment, which the browser never sends to a server.
If I change the wrong thing, can I undo it?
Yes. The editor keeps a bounded history of every value and structural change: ⌘/Ctrl + Z steps back, ⌘/Ctrl + Shift + Z forward, and Clear, Sample and Format each count as one undoable step. While the raw text view has focus, the browser's own text undo takes over instead.
Keyboard shortcuts
- ⌘/Ctrl + Enter
- Parse the current text now — required past 2 MB, even with the cursor still in the text view.
- ⌘/Ctrl + S
- Download the current document as a .json file, overriding the browser's own save shortcut here.
- ⌘/Ctrl + C
- With nothing selected, copy the active value exactly as written — the whole document when no value is active; a real selection copies itself.
- ⌘/Ctrl + Shift + C
- Copy the whole document to the clipboard, no matter what is selected or where focus sits.
- ⌘/Ctrl + Z
- Undo the last edit; value and structural edits share one bounded history. In the raw text view the browser's native undo takes over.
- ⌘/Ctrl + Shift + Z
- Redo the edit you just undid, from the same bounded history.
- t
- Cycle the color theme; single keys stay inert while you are typing in a field or composing with an IME.
- ? or ⌘/Ctrl + /
- Open keyboard help, including the tree and table widget keys: arrows to move, Enter to edit a value, Tab across table cells, and Home/End to jump to the ends.
- Esc
- Close the topmost dialog or cancel the cell you are editing; it never clears your document.