Loading the JSON generator…

Generate random JSON test data from a template

Writing fixtures by hand is slow and the result is always too small and too tidy to find anything. This generates a document from a template you control — a hundred records or a hundred megabytes — in the browser, from a closed set of tags rather than from code.

The template is JSON

There is no separate language to learn. A template is a JSON document in which any string may contain a {{tag}}, and an array whose first element is "{{repeat(n)}}" repeats the element after it. Everything else in the template is copied through untouched.

{
  "users": [
    "{{repeat(3)}}",
    {
      "id": "{{seq(1, 1)}}",
      "name": "{{fullName()}}",
      "email": "{{email()}}",
      "signedUpAt": "{{date('2024-01-01', 'now', 'iso')}}",
      "plan": "{{weighted('free', 8, 'pro', 2)}}",
      "nickname{{optional(0.5)}}": "{{firstName()}}"
    }
  ]
}

generates

{
  "users": [
    {
      "id": 1,
      "name": "Grace Liskov",
      "email": "grace.liskov@example.com",
      "signedUpAt": "2024-11-03T09:12:44.081Z",
      "plan": "free"
    },
    {
      "id": 2,
      "name": "Vint Hamilton",
      "email": "vint.hamilton@example.org",
      "signedUpAt": "2025-06-21T17:40:02.517Z",
      "plan": "pro",
      "nickname": "Ada"
    }
  ]
}

A string that is exactly one tag takes that tag’s own type: "{{integer(1,9)}}" generates the number 7, not the string "7". A tag with text around it interpolates, because that is the only thing it could mean.

Tag reference

TagGenerates
{{repeat(n)}} · {{repeat(min, max)}}Repeats the following array element. As the first element of an array only.
{{index()}}The 0-based position within the enclosing repeat. {{index(1)}} is the level above.
{{seq(start, step)}}A counter that advances once per element — sequential ids that do not collide.
{{integer(min, max)}}A whole number, both ends inclusive.
{{floating(min, max, decimals)}}A decimal number rounded to decimals places.
{{bool(p)}}true with probability p, default 0.5.
{{date(start, end, format)}}A date between two ISO dates or now. Formats: iso, date, time, epoch, epochMs.
{{oneOf(a, b, c)}}One of the arguments, evenly. null is a valid option.
{{weighted(a, 9, b, 1)}}One of the values, drawn by its weight.
{{guid()}} · {{objectId()}} · {{hex(n)}}A version-4 UUID, a 24-character ObjectId, or n hex characters.
{{ref(pointer)}}A value already generated at a JSON Pointer, with * matching any array index.
{{lorem(n, unit)}}Filler text. Units: words, sentences, paragraphs.
{{fullName()}} · {{firstName()}} · {{surname()}}A person’s name.
{{email()}} · {{phone()}}Contact details. Addresses use reserved domains, so they cannot be delivered.
{{street()}} · {{city()}} · {{zip()}} · {{country()}}An address.
{{company()}} · {{department()}} · {{product()}} · {{status()}}Business filler.
{{ip()}} · {{url()}} · {{domain()}} · {{semver()}}Network and release values.
{{currency()}}An ISO 4217 currency code.
"key{{optional(p)}}"As a key suffix: the property is present with probability p.

References between collections

Generated data is usually useless the moment anything has to join. An array of orders whose userId values match no user tests nothing. {{ref()}} points one collection at another using a JSON Pointer, where * matches any array index:

{
  "users":  ["{{repeat(8)}}",  { "id": "{{seq(1,1)}}", "name": "{{fullName()}}" }],
  "orders": ["{{repeat(40)}}", { "userId": "{{ref('/users/*/id')}}", "total": "{{floating(5, 500, 2)}}" }]
}

A reference resolves against values that have already been generated, so the collection being referenced has to appear earlier in the template than the reference to it. A reference to something not yet generated produces null rather than failing the document, because a template being edited is usually in exactly that state for a few keystrokes.

The same seed gives the same document

Every generation reports the seed it used, and typing that seed back in reproduces the document byte for byte. That is what makes generated data usable as a fixture: the file can be regenerated in CI rather than committed, and a bug found in a generated document can be handed to someone else as a seed instead of a 40 MB attachment.

One caveat worth knowing: {{date(…, ’now’)}} follows the clock. A generation that has to be identical next week should name both ends of its date range.

Start from a JSON Schema

Paste a JSON Schema in place of a template and the page offers to convert it. Required properties stay, everything else becomes an {{optional()}} key, enum becomes {{oneOf()}}, minimum and maximum become the bounds of the number tag, minItems and maxItems become the repeat range, and a format of uuid, email, date-time, date, ipv4, uri or hostname becomes the tag that satisfies it. Local $ref pointers into $defs are followed, and a recursive one stops rather than running away.

It converts to a template, not straight to data, and that is the point. A schema can say a field is a date-time; only you can say it should fall in the last ninety days. Going through the template makes that a one-line edit instead of an argument with a converter. It also closes a loop: JSONParse can generate a schema from a document, and that schema comes back here as a generator for a thousand more documents like it.

Sizes the other generators will not reach

Most online generators build the whole document as an in-memory object and then serialise it, which puts a practical ceiling of a few megabytes on the answer — and they do it on a server, so the ceiling is theirs and not yours. This one writes the output as text as it goes and watches the byte counter while it writes, so asking for 200 MB of NDJSON costs roughly 200 MB, once.

Set a size rather than a count and the outermost repeat keeps going until the document reaches it. That is the fastest way to get a file large enough to find out what your own tooling does with one — and the viewer next door will open the result. See how large files are handled.

Nothing in a template is executed

Other template-based generators let you embed JavaScript and run it. This one does not, and the difference is deliberate. The page is served with a Content-Security-Policy that has no unsafe-eval, and a document generator that can run code is a page that will eventually run someone else’s code from a shared template link. The tags are a closed set with literal arguments — which is why {{seq()}}, {{weighted()}} and {{ref()}} exist at all, since those are what the escape hatch was normally used for.

From a script or an agent

The same generator is an HTTP endpoint at /api/mock and an MCP tool named generate_json, so a test suite or an assistant can produce fixtures without a browser. Pass the template as the json property and a seed when the result has to be repeatable. See the API reference and the MCP guide.

curl -s https://jsonparse.online/api/mock \
  -H 'content-type: application/json' \
  -d '{"json":"[\"{{repeat(3)}}\",{\"id\":\"{{seq(1,1)}}\",\"name\":\"{{fullName()}}\"}]","options":{"seed":"demo"}}'

The browser generator never transmits anything. The API by definition receives the template you send it — it is the template, not a document, but the boundary is the same one described on the privacy page.

Open the viewerNo sign-up, no upload, no file size dialog.

Frequently asked questions

Is the generated data sent to a server?

No. Generation runs in a Web Worker in your own browser, the same way parsing does. The template and the generated document both stay on your machine. There is a separate HTTP API for scripts, which does receive what you send it, and that difference is stated on the privacy page.

Can I generate the same JSON twice?

Yes. Every generation reports the seed it used, and entering that seed with the same template reproduces the document exactly. The only exception is a date range ending in "now", which follows the clock; name both ends of the range if the output has to be identical later.

How much JSON can it generate?

Hundreds of megabytes. The output is written as text as it goes rather than built as objects and serialised, so the cost is close to the size of the file itself. Set a target size instead of a record count and the outermost repeat keeps going until the document reaches it.

Can generated records reference each other?

Yes, with the ref tag. It takes a JSON Pointer in which * matches any array index, so orders can carry userId values drawn from ids already generated in a users collection. References resolve against data generated earlier in the template.

Does it run JavaScript in the template?

No, and this is deliberate. The tags are a closed set taking literal arguments, so a template cannot execute anything. Sequential ids, weighted choices and cross-references have dedicated tags precisely because those are what an embedded scripting escape hatch is normally used for.

Can I generate JSON from a JSON Schema?

Yes. Paste a schema in place of a template and the page offers to convert it: required properties stay, enum becomes a choice, numeric bounds and item counts carry across, and formats such as uuid, email and date-time become the matching tag. It converts to a template rather than straight to data, so you can then adjust the ranges the schema could not express.