ZeroUtil
Developer Tools

The Developer's JSON Guide: Everything Worth Knowing About JSON in 2026

A comprehensive guide to JSON — the spec, the variants, the tooling, debugging, JWT and Base64 context, and how to ship systems that don't break on malformed payloads.

By · · 9 min read

JSON is the most-used data interchange format in the world. It’s in HTTP APIs, configuration files, databases, logs, and the network tab of every browser you’ve ever opened. Despite its ubiquity — or because of it — a lot of working developers never sit down with the full picture. This guide is the “one place” I wish existed when I started out.

It’s long. That’s deliberate. If you want a specific topic, jump straight to the section.

Part 1: what JSON actually is

JSON was defined in the early 2000s as a subset of JavaScript’s object literal syntax. The goal was simple: a data format that was easy for humans to read, easy for machines to parse, and language-neutral enough that a Python service could talk to a Java service via a string without either caring what the other was written in.

The official spec — RFC 8259 — defines a tiny grammar:

  • Objects (key/value pairs, keys must be strings)
  • Arrays (ordered values)
  • Strings (double-quoted, with a specific escape set)
  • Numbers (decimal)
  • true, false, null

No comments. No trailing commas. No dates. No binary. No named references. The spec is deliberately minimal.

This minimalism is the source of both its success (parsers are cheap, implementations are consistent) and its recurring annoyances (config files want comments, APIs want dates, binary needs encoding).

Part 2: the variants

Within a year or two of JSON becoming popular, the ecosystem started producing variants that added back features the spec left out. The three you’ll encounter are:

  • JSON (RFC 8259): the strict spec.
  • JSONC: JSON with comments. Used extensively by VS Code (settings.json, tsconfig.json). No trailing commas.
  • JSON5: a broader extension including comments, trailing commas, unquoted keys, hex numbers, and a few other JavaScript-ish features. Used by some build tools and configuration systems.

These look nearly identical but parse differently. A file ending in .json might be any of the three depending on who’s consuming it. For a detailed walkthrough of the differences, see JSON vs. JSON5 vs. JSONC.

The practical rule: use plain JSON for anything crossing service boundaries. Use JSONC for human-edited configs that a specific tool (like VS Code) natively supports. Reach for JSON5 only when you’ve explicitly decided to trade portability for ergonomics.

Part 3: common operations

Formatting and validation

Minified JSON (one long line, no whitespace) is what servers send. Formatted JSON (indented, one key per line) is what humans read. A good formatter accepts either input and produces readable output.

Our JSON Formatter runs entirely in the browser — paste any JSON payload and get a validated, pretty-printed version. If the input is invalid, the formatter reports the exact character position of the first syntax error, which is the fastest path to finding what’s wrong.

Converting to other formats

JSON is fine for machine-to-machine, but other contexts demand other formats:

  • CSV for spreadsheets: if you need to get an array of JSON objects into Excel or Google Sheets, use our JSON to CSV converter. The conversion handles nested objects with dot notation.
  • YAML for human-editable configs: some tools prefer YAML (Kubernetes manifests, GitHub Actions, docker-compose). Our JSON to YAML converter handles the structural differences, and the reverse for converting existing YAML.
  • TOML for simple key/value: pyproject.toml, Cargo.toml, many modern config formats. Convert with TOML to JSON when feeding TOML configs into JavaScript tooling.

Debugging malformed input

Every developer hits a SyntaxError: Unexpected token at some point. The debugging process is well-trodden:

  1. Paste the payload into a formatter; look at the reported position.
  2. Check for the common culprits: trailing comma, unquoted keys, unescaped newlines in strings, a BOM at the start of the file.
  3. If the payload came from an API, check whether the response was truncated — the last character should be } or ], not mid-string.

A full playbook lives in Debugging Malformed JSON: A Field Guide.

Part 4: how JSON interacts with other formats

Base64

When JSON needs to carry binary data (an image, a PDF, a public key), it can’t embed the raw bytes. Strings in JSON are Unicode text, and binary bytes are not valid Unicode. The standard workaround is Base64 encoding: the bytes get represented as a string of printable ASCII characters.

A JSON response with an embedded image might look like:

{
  "filename": "avatar.png",
  "content": "iVBORw0KGgoAAAANSUhEUgAA..."
}

The content field is Base64. Decoding it gives you the original PNG bytes.

Base64 isn’t encryption — anyone who can read the JSON can decode the Base64. The full story is in Base64 Explained, including the URL-safe variant you’ll see in JWTs.

JWTs

A JSON Web Token is three Base64-URL-encoded parts separated by dots. The middle part is a JSON object (the “payload” or “claims”). Decoding a JWT’s payload is just Base64-URL decoding followed by parsing JSON.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9    <- Base64URL of {"alg":"HS256","typ":"JWT"}
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZS...    <- Base64URL of the payload (JSON)
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV...    <- signature bytes, also Base64URL

You can inspect any JWT with our JWT Decoder — it decodes the payload without validating the signature, which is useful for debugging and not useful for security (don’t trust a JWT you haven’t cryptographically verified).

For the security pitfalls around JWT verification — algorithm confusion, weak secrets, missing expiry — see JWT Authentication Mistakes.

Part 5: the numbers problem

JSON numbers are a source of subtle bugs. The spec allows arbitrary decimal numbers, but most parsers represent them as IEEE 754 double-precision floats. This has consequences:

  • Integer precision is capped at 2^53 (about 9 × 10^15). Larger integers — Twitter’s 64-bit IDs, some database primary keys — get mangled. The canonical fix is to serialize them as strings ("id": "1234567890123456789"), not numbers.
  • Decimal arithmetic is inexact. 0.1 + 0.2 is 0.30000000000000004 when serialized; if you need exact decimals (financial calculations), use string representations.
  • NaN and Infinity aren’t valid JSON values, but some parsers emit them anyway. Prefer representing “unknown” as null or as a separate field.

The serialization you send is not always what the consumer receives. Test round-tripping of large integers and high-precision decimals before shipping a system that depends on either.

Part 6: schemas and validation

For APIs with any complexity, ad-hoc validation gets painful fast. Two standards worth knowing:

  • JSON Schema: a JSON-based format for describing the shape of other JSON documents. Broadly supported, widely used for API request/response validation.
  • OpenAPI: a superset of JSON Schema focused on describing HTTP APIs. If you’re shipping an API meant to be consumed by outside developers, OpenAPI gives them generated client code for free.

For smaller projects, type-aware libraries like Zod (TypeScript) and Pydantic (Python) provide schema validation with less ceremony than full JSON Schema. They’re not interchangeable formats, but they solve the same problem for internal use.

Part 7: performance considerations

JSON is a text format. For high-throughput systems, this matters:

  • Parsing cost: native JSON parsing is fast (typically a few hundred MB/s for modern implementations) but not free. At sustained gigabit speeds, it can be a measurable fraction of CPU.
  • Payload size: JSON is less compact than binary alternatives. Gzip compression on JSON usually gives ~3-10× reduction; brotli does a bit better.
  • Streaming: standard JSON parsers load the whole document into memory. For huge documents, you need a streaming parser (stream-json in Node, ijson in Python).

When JSON becomes the bottleneck, the usual next steps are (in order):

  1. Enable HTTP compression (gzip/brotli) — 10× smaller payloads for free.
  2. Strip unused fields before serializing — often half your payload is fields nobody reads.
  3. Consider a binary format (Protocol Buffers, MessagePack, CBOR) for internal service-to-service communication where human readability doesn’t matter.

Most systems don’t hit JSON’s limits; the payload size and parse cost are a rounding error compared to the database and network. But at scale, they’re real.

Part 8: security implications

JSON is data, not code — but data can still cause trouble:

  • JSON injection: if you build JSON by string concatenation instead of proper serialization, user input can escape the string and modify the structure. Always use your language’s JSON.stringify or equivalent.
  • Billion-laughs-style denial of service: deeply nested JSON can crash parsers that don’t cap recursion depth. Most modern parsers have sane defaults; verify yours does.
  • Large payload DoS: a parser that buffers the whole document before processing can be DoSed with a huge input. For public APIs, cap request body size aggressively.
  • Prototype pollution (JavaScript-specific): parsing JSON with a __proto__ key into a plain object is mostly safe, but using it as a lookup table creates attack surface. Prefer Map over Object for untrusted keys.

Part 9: the operational side

Logging JSON

Structured logs in JSON are easier to grep, aggregate, and ship to log services than unstructured text. The convention:

{"ts":"2026-04-21T14:40:00Z","level":"info","msg":"user signed in","user_id":42}

One record per line (this is “newline-delimited JSON” or “ndjson”). Tools like jq, fluentbit, and most log aggregators handle this natively.

Comparing JSON

Diffing two JSON files as plain text rarely works — formatting differences and key reordering make the diff unreadable. Use tools that normalize first (sort keys, strip whitespace) and then compare.

Version control

A huge JSON file in git becomes a mergeability problem — every concurrent edit conflicts. If you have a config that multiple people edit, consider either splitting it into multiple smaller files or using a format (YAML, TOML) that’s easier for text-based merge tools.

Closing: the practical JSON attitude

JSON has been the lingua franca of APIs for twenty years, and it’s still the default in 2026. It’s boring. That’s good. Boring formats are reliable ones.

The working developer’s job with JSON is mostly not “understand the format” — it’s “understand the edge cases.” Unicode in strings, large numbers, date serialization, and the handful of security pitfalls are what separate confident JSON-wielding from frustrated JSON-debugging.

The tools linked throughout this guide — formatter , CSV converter , Base64 , JWT decoder — all run in the browser and don’t transmit your input anywhere. For sensitive payloads (production database dumps, API keys, tokens), that property matters.

And for the adjacent topics: the cluster articles linked throughout cover each piece in more depth. This guide is the map; those are the territory.

Tools mentioned in this article

Related articles