Every JSON tool on the internet says "nothing is uploaded" or "runs entirely in your browser." That sentence is not a differentiator by itself — it's the same five words on five competitors' landing pages. What's actually different here is that the claim is enforced by the browser, not merely promised by us, and you can check that in under a minute without trusting anything we say on this page.
Don't take the rest of this page's word for any of this. Two checks, both doable right now against the live app at jsonwebviewer.com:
jsonwebviewer.com) and nothing else — no request to any other
domain, ever, no matter what you type into either panel.
We ran both of these checks ourselves before publishing this page, against a real production build,
not a hand-picked demo: a scripted browser session showed zero requests to any non-jsonwebviewer.com
origin during normal use, and a full page reload with the network adapter simulated offline
(context.setOffline(true)) still rendered the working app. The instructions above
describe exactly what that check did — running them yourself should reproduce the same result.
This is not a summary or a paraphrase — it is copied character-for-character from the
Content-Security-Policy header the production server actually sends
(jsonwebviewer/src/public/.htaccess, the same file that ships to the live site on
every deploy). Load the app and check DevTools → Network → the document request → Response
Headers and you will see this exact string:
default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'
The directive that matters most for this claim is connect-src 'self'. In plain
language: the browser itself refuses to open any network connection — fetch,
XMLHttpRequest, WebSocket, whatever — to any origin other than
jsonwebviewer.com. This is not something our JavaScript chooses to do and
could quietly choose not to do in a future release; it is enforced by the browser's own CSP engine,
underneath and independent of our code. If a future bug, a compromised dependency, or a malicious
contributor tried to add a call home, the browser would block it and log a CSP violation — it would
not silently succeed. The guarantee does not rest on trusting our intentions; it rests on a
mechanism the browser enforces regardless of them.
The rest of the policy closes off the other obvious ways a tool could leak or be hijacked, since a
privacy claim that only covered network calls and left the DOM open to injection wouldn't be worth
much: script-src 'self' (no inline scripts, no eval) means an XSS payload
smuggled in through a malicious JSON document has nowhere to execute from —
'wasm-unsafe-eval' is the one narrow addition, and it permits
only WebAssembly.compile-family calls for the jq engine below, never
eval()/Function(); object-src 'none',
base-uri 'none', and frame-ancestors 'none' close off plugin embeds,
base-tag hijacking, and clickjacking respectively; form-action 'none' means there is no
form on this site that could ever submit anywhere, because there is no form. style-src 'self'
'unsafe-inline' is the one deliberately loosened directive, scoped to styles only (never
scripts) — CodeMirror 6, the code editor this app is built on, injects its syntax-highlighting theme
via inline <style> elements at runtime, and a strict style-src would
leave the editor completely unstyled. That trade-off is scoped as narrowly as the editor allows and
does not touch script execution at all.
A reviewer can falsify "nothing else loads" in one look at the Network tab, so here is the honest, specific inventory rather than an absolute claim that invites exactly that look:
jsonwebviewer.com. No Google Fonts, no CDN-hosted library, no third-party script tag
anywhere in the page.
jq-wasm, real jq 1.8.2 compiled to
WASM), fetched lazily — only the first time you actually run a jq query in the Transform modal, not
on page load. This is what 'wasm-unsafe-eval' above exists for; it's still served
from this origin, same as everything else.
exceljs), fetched lazily only when you
actually export a document to .xlsx. Same origin, same lazy-loading pattern.
This app ships shareable links, and server-side share/save features are exactly the class of feature that has gone wrong elsewhere: publicly-reported research has found tens of thousands of documents left readable on other online JSON tools' save/share endpoints, because those tools store what you paste on a server somewhere and hand back a link to it. A reviewer who knows that history is right to be suspicious of "share a link" on a client-side tool specifically.
This implementation is different in a way that's checkable, not just asserted: clicking
Share compresses your document (gzip, via the browser's own built-in
CompressionStream) and encodes the result directly into the URL's #
fragment — the part of a URL after the hash mark. A URL fragment is never sent to any
server by design; it's a piece of web-platform behavior that predates this app and that no
server-side code, ours or anyone else's, can override. Opening a shared link decompresses the
fragment back into a document entirely in the recipient's own browser. At no point does the document
exist on any server we operate — there is no server-side store for it to exist on. The same
connect-src 'self' policy above applies to the Share action exactly like everything
else: generating or opening a share link causes no network request at all.
The one honest limit worth naming: because the whole document rides in the URL itself, extremely large documents (tens of thousands of characters) hit browser URL-length practicalities and get a graceful "too large to share via link — use Save to disk instead" message rather than silently truncating your data. That's a size ceiling, not a privacy trade-off — nothing partially shared ever touches a server either.
A reviewer who finds one glossed-over exception discards the whole document, so here's every one we know of, stated plainly rather than buried:
<head> carries a <meta name="google-site-verification"> tag,
and a matching static file sits at the site root — both exist purely so Google can confirm we own
this domain for Search Console. Neither causes your browser to make any additional network
request, and neither is related to your document in any way: they're static strings in
already-public page markup, read by Google's own crawler when it visits the site on its own
schedule, not sent by your browser to anyone on your behalf. Included here for completeness, not
because it weakens the guarantee above.
One structural point worth stating precisely, because it reframes the conversation rather than just
asserting trustworthiness: a tool that never transmits your data is not a business
associate, because no disclosure occurs. If a document never leaves your browser, it was
never shared with us, processed by us, or stored by us in any sense a data-processing agreement
exists to govern — there's no server-side event for such an agreement to describe. This is a
statement about the mechanism above (enforced by connect-src 'self', not by policy), not
legal advice, and it doesn't substitute for your own organization's assessment. It's offered so that
assessment can start from what's actually true rather than from marketing copy that merely claims
privacy.
Enforced. connect-src 'self' is a Content Security Policy directive read and applied
by the browser itself, independent of our JavaScript. If our code (or a compromised dependency)
tried to send a request to another origin, the browser would block it and log a CSP violation —
it would not depend on us behaving correctly.
A ~929 KB WebAssembly build of jq, fetched only the first time you run a jq query, and a ~930 KB Excel-export library, fetched only when you export to .xlsx. Both are served from jsonwebviewer.com, same as everything else — no third-party CDN, no analytics, no ad network.
The document is compressed and encoded directly into the URL's # fragment, which
browsers never send to a server by design. There is no server-side store the document is written
to — nothing exists there for a link to expose, unlike tools that upload your paste to a server
and hand back a link to it.
Not your document, and not anything derived from it — that's what connect-src 'self'
enforces. The one static exception is a Google Search Console domain-verification tag/file, which
is unrelated to your document, causes no additional browser request, and is read only by Google's
own crawler on its own schedule.
Yes — that's the point of this page. Open DevTools' Network tab and use the app normally to watch for outbound requests, or disconnect from the network entirely after your first visit and confirm the app keeps working. Both are described above in enough detail to actually run them.
Want to try the app itself? Open the editor or browse every tool in one place.