Free · Fast · Privacy-first

Validate JSON in JavaScript

In JavaScript, the only built-in way to validate JSON is to call JSON.parse() inside a try-catch block.

Understand what JSON.parse accepts and rejects

🔒

Clear error positions easier to read than V8 messages

Debug SyntaxError causes before writing code

Free, browser-based, instant feedback

Cost
Free forever
Sign-up
Not required
Processing
In your browser
Privacy
Files stay local
FreeNo signupWhite-label

Add this JSON Validator to your website

Drop the JSON Validator into any page — blog post, product docs, intranet, school portal — with a single line of HTML. Your visitors get the full tool, processed entirely in their browser. No backend, no uploads, no signup.

  • Files stay 100% in the visitor's browser
  • Responsive — adapts to any container width
  • Free forever, no API key needed

Embed code

<iframe
  src="https://www.fixtools.io/json/json-validator?embed=1"
  width="100%"
  height="780"
  frameborder="0"
  style="border:0;border-radius:16px;max-width:900px;"
  title="JSON Validator by FixTools"
  loading="lazy"
  allow="clipboard-write"
></iframe>

Attribution-friendly: a small "Powered by FixTools" link appears in the embed footer.

JSON.parse SyntaxError: What the Error Message Tells You and What It Does Not

JSON.parse() is the only built-in JSON validator in standard JavaScript. It is a synchronous function that either returns the parsed value or throws a SyntaxError. There is no JSON.tryParse, no boolean-returning validator, and no asynchronous variant. The thrown error message varies meaningfully across engines. V8, which powers Node.js, Chrome, and Edge, reports a token name and a short snippet from the failing string, such as: SyntaxError: Unexpected token ',', "...'amount'..." is not valid JSON. SpiderMonkey, the Firefox engine, includes a line and column number directly in its message, which is easier to act on. JavaScriptCore, used by Safari, reports a terser message like Expected '}'. The inconsistency means any cross-browser logging strategy has to capture both the raw message and the input string for later diagnosis.

A reliable validation pattern in JavaScript wraps the parse in a small utility that decides what to do on failure. The simplest version is function isValidJSON(str) { try { JSON.parse(str); return true; } catch { return false; } }. A richer version returns either the parsed value or a structured error: function parseJSON(str) { try { return { ok: true, value: JSON.parse(str) }; } catch (e) { return { ok: false, error: e.message, input: str }; } }. Returning the input alongside the error message in the failure branch is what makes the result useful for debugging later, when the original variable is no longer in scope. Recent Node.js versions and browsers also attach a cause property to SyntaxError in some scenarios, which can carry additional context.

For development workflow, a browser-based validator like FixTools converts a raw SyntaxError into something immediately actionable. Paste the string that JSON.parse rejected, and you get the line and column rather than a single character offset, plus a description of what the parser expected at that position. Once you have identified the underlying cause, you can fix it at the source: the template that produced the trailing comma, the serialiser that emitted NaN, the storage layer that introduced a BOM byte. Fixing the source eliminates the failure permanently. Patching the parser with regex preprocessing only papers over a generator that will keep producing broken JSON until someone fixes it.

For production-grade JavaScript code, layer schema validation on top of the basic JSON.parse syntax check using AJV. AJV is the de facto standard JSON Schema validator for JavaScript and supports drafts from 4 through 2020-12 with full keyword coverage. The typical pattern is to compile each schema once at startup, store the resulting validate function in a registry keyed by route or message type, and call validate on every parsed value before the application logic runs. Compilation produces highly optimised inline code that runs significantly faster than tree-walking validators in other languages. A migration path from draft-07 to Draft 2020-12 mostly involves renaming definitions to $defs and updating any uses of $recursiveRef to $dynamicRef, both of which AJV handles transparently when you point the $schema declaration at the newer draft URL. Wire the validator into Express, Fastify, or Koa middleware so every inbound request body and every outbound response payload passes through validation before reaching downstream code.

How to use this tool

💡

Paste a JSON string that is failing in your JavaScript code. FixTools shows the parse error with line, column, and description, more readable than a raw SyntaxError.

How It Works

Step-by-step guide to validate json in javascript:

  1. 1

    Identify the failing string

    Add console.log(JSON.stringify(yourString)) immediately before your JSON.parse() call. Wrapping the value in stringify reveals invisible characters, BOM bytes, and whitespace that a plain log would obscure. Capture the output exactly as printed, including the surrounding quotes the stringify call adds for you.

  2. 2

    Paste into FixTools

    Copy the logged contents from your terminal or browser console and paste it into the FixTools JSON validator. If you used JSON.stringify in the log, strip the outer wrapping quotes and unescape the inner quotes before pasting so the validator sees the same bytes your parse call received.

  3. 3

    Read the error

    FixTools converts the raw character offset into a readable line and column reference and adds a description such as Expected comma between values or Unexpected closing brace after comma. The location lands directly on the offending character so you can navigate to it in your editor without counting bytes.

  4. 4

    Fix the source

    Update the template, serialiser, schema generator, or data entry path that produced the broken JSON. Fixing the source prevents the same failure from recurring on every subsequent record. Patching only the captured sample is faster but leaves a generator that will keep emitting invalid output for other callers.

  5. 5

    Test in code

    Re-run your JavaScript with a representative input set, not just the previously failing case. Add a unit test that pins the exact failure shape so any regression in the upstream serialiser is caught before it reaches production. JSON.parse should now return cleanly without throwing for every input.

Real-world examples

Common situations where this approach makes a real difference:

Node.js developer

A developer writes a config loader that reads a JSON file from disk and parses it on startup. In staging the parse succeeds, but production crashes on one host with Unexpected token }. They add a console.log of the buffer before parsing, paste the captured string into FixTools, and discover a trailing comma at line 22 that was added when an operator hand-edited the file in vi on that host. The fix is to rebuild the file from the canonical template and reject hand edits in deployment.

React developer

A React app persists feature flags in localStorage as a JSON string. After a browser update, the app throws on startup when reading the value. The developer inspects the value in DevTools, pastes it into FixTools, and finds a non-breaking space at U+00A0 introduced when a user pasted a label from a rich text editor. They add a sanitisation step that strips non-printing Unicode before writing, and a validation step that resets the cache if the read fails. The crash stops recurring across the user base.

Full-stack developer

A developer calls a third-party API and calls JSON.parse on the response text directly. Most days the call succeeds. When the vendor is in maintenance, the call throws because the gateway returns an HTML status page. They wrap the call in a content-type check and a status code guard, then use FixTools to confirm the shape of the maintenance response. The defensive code returns a typed error to the caller instead of leaking a SyntaxError to the UI layer.

Junior developer learning JSON

A student writes their first Express API and posts a body with unquoted keys to a local endpoint. The express.json middleware rejects the request with a 400 and a terse parse error. They paste the body into FixTools, see each unquoted key flagged with its line and column, and read the description explaining that JSON requires double-quoted property names even though JavaScript object literals do not. The visual feedback cements the rule more quickly than reading the spec.

Pro tips

Get better results with these expert suggestions:

1

Always validate before JSON.parse in production

For data arriving from outside your process, validate the shape before calling parse rather than relying on try-catch alone. A validation step gives you a place to log the raw input, return a structured error to the caller, and emit a metric. A bare try-catch swallows the failure and leaves you with no record of what arrived, which makes recurring parse failures invisible until a user complains.

2

Use a reviver function for type coercion

JSON.parse accepts an optional second argument, a reviver function, that receives every key and value pair as the structure is built. Use it to coerce ISO date strings into Date instances, to rename legacy fields, or to wrap big integers in a BigInt-aware type. The reviver runs after parsing succeeds, so it cannot rescue a syntactically invalid string. Validate the bytes first, then transform the parsed structure.

3

Log the raw string, not the error message

When a JSON.parse call throws, the SyntaxError message is often less useful than the input that triggered it. Log the input first, ideally wrapped in JSON.stringify so invisible characters become visible, and only then log the error message. A failure log with the input attached can be replayed in FixTools immediately. A log with only the message forces you to reconstruct the failing case from memory.

4

Wrap JSON.parse in a utility function

Centralise JSON parsing in a single helper that handles logging, error wrapping, telemetry, and fallback behaviour. Every call site uses the helper instead of calling JSON.parse directly. This guarantees that all parse failures across the codebase produce structured output with the same shape, which makes dashboards and alerts uniform. Scattering try-catch blocks across handlers produces inconsistent error reports that are hard to monitor.

FAQ

Frequently asked questions

The canonical approach is to call JSON.parse inside a try-catch block. When the string conforms to RFC 8259, parse returns the populated value. When it does not, the engine throws a SyntaxError that your catch clause receives. The minimal helper is function isValidJSON(str) { try { JSON.parse(str); return true; } catch { return false; } }. For debugging during development, paste the failing string into FixTools to get a line and column reference plus a description, which is far easier to act on than the raw engine message.
JSON.parse throws a SyntaxError, but the message text varies by engine. V8, used by Node.js and Chrome, reports the token character and a short snippet from the failing input. SpiderMonkey, used by Firefox, includes a line and column number directly. JavaScriptCore, used by Safari, gives the terser Expected closing brace shape. Any cross-browser code that inspects the message needs to handle all three formats, which is why a normalised validator like FixTools is more reliable for human debugging.
In the standard library, yes. JSON.parse has no success-indicating return value and no companion function that returns a boolean. There is no JSON.tryParse, no JSON.validate, and no asynchronous variant. Utility libraries such as lodash provide attempt helpers that catch errors from a callback, but the underlying mechanism is still try-catch. If you want validation without parsing, you would need to ship a JSON grammar parser yourself, which is rarely worth the bundle size.
Catch it, log the input alongside the message, and either return a typed error to the caller or re-throw with additional context. A useful log line looks like Failed to parse JSON: <message> Input: <first 200 characters>. Slicing the input prevents enormous payloads from filling your log storage while still giving you enough context to reproduce. In an HTTP handler, translate the SyntaxError into a 400 Bad Request rather than letting it propagate to a 500.
Firefox includes line and column in the SyntaxError message directly. Recent V8 versions sometimes include a position offset that you can convert to a line and column by counting newlines in the input. Older V8 versions omit position information entirely. Because the format is not standardised, the reliable way to get a line and column during development is to paste the failing string into FixTools, which normalises the location across engines.
No. JSON.parse only checks that the string conforms to the JSON grammar defined in RFC 8259. It does not check that the parsed object has specific fields, correct types, or value ranges. For schema validation, layer a JSON Schema library on top: AJV is the standard choice in JavaScript and supports drafts 4 through 2020-12. Always perform syntax validation first, then run the parsed structure through schema validation. The two checks fail for different reasons and produce different error messages.
JSON.parse is safe from code injection because it is a pure data parser. It cannot evaluate JavaScript expressions, call functions, or trigger getters and setters during parsing. This is the key safety difference from the historical pattern of using eval to parse JSON. However, untrusted input can still cause problems: a deeply nested structure can exhaust the call stack, and a very large string can exhaust memory. For public-facing APIs, enforce a size limit on the request body before parsing.
JSON.parse converts every JSON number into a JavaScript number, which is an IEEE 754 double. Integers above Number.MAX_SAFE_INTEGER, which is two to the 53 minus one, lose precision silently. For example, JSON.parse('{"id": 9007199254740993}').id returns 9007199254740992. If your JSON contains large integer identifiers, parse with a BigInt-aware library such as json-bigint, or use a reviver to capture the raw string for fields you know exceed the safe integer range.
Add a step to your GitHub Actions or GitLab CI workflow that runs a small Node.js script which loads each JSON file in the repository, parses it inside try-catch, and exits with a non-zero status on the first failure. The script can be as short as ten lines using fs.readFileSync and JSON.parse over a glob of file paths. For schema validation on top of syntax checking, add an AJV step that loads the schemas directory, compiles each schema, and validates the corresponding fixtures or examples. Tools like jsonlint and ajv-cli wrap both passes into single commands you can call directly from a pipeline step without writing custom code. The earlier in the workflow you catch broken JSON, the cheaper the fix, so prefer pre-commit hooks at the developer machine and CI checks on the server side as a belt-and-braces defence that catches regressions before they reach reviewers or production deployment artifacts.

Ready to get started?

Open the full JSON Validator — free, no account needed, works on any device.

Open JSON Validator →

Free · No account needed · Works on any device