Mock JSON Generator, Explained
After reading this you will know how a JSON template with placeholders like {{name}} and {{int 1 100}} expands into any number of realistic records, when to use fake data instead of real data, and how to avoid the common traps that produce malformed or misleading output.
What it does and one quick example
The Mock JSON Generator takes one JSON template that describes a single record, then produces many copies of that record with the placeholders replaced by fresh fake values each time. You write the shape once and get an array of records back.
Here is a minimal template:
{"id": "{{int 1 1000}}", "name": "{{name}}", "active": "{{bool}}"}
Ask for 3 records and you get output like this:
[{"id": 742, "name": "Maria Alvarez", "active": true}, {"id": 118, "name": "Chen Wei", "active": false}, {"id": 903, "name": "Jonas Berg", "active": true}]
Notice two things. The id and active values are no longer strings: they became a real JSON number and a real JSON boolean. That happens because each placeholder was the only content of its string. The name stayed a string because names are text.
When to use fake data, and when not
Reach for generated data when you need volume and variety without caring about the exact values. Three common cases:
- Seeding a test database. You want 500 users to check pagination, not 500 hand-typed names.
- Mocking an API response. Your frontend needs a realistic payload before the backend endpoint exists.
- Demos and screenshots. You want plausible content that does not expose real customer records.
Do not use generated data when the values must be correct. Fake data will not satisfy a foreign key constraint, will not match a real payment token, and will not pass a checksum on a fake IBAN or credit card number. If a downstream system validates the value, generate something that only looks right and it will be rejected.
Never seed a production system with mock data. A generated email like [email protected] can bounce, trigger real sending attempts, or collide with a real account if your uniqueness check is weak. Keep fake data in test and staging only.
How placeholder expansion works
A placeholder is a token wrapped in double braces: {{...}}. The generator scans the template text, finds each token, and calls the matching generator function once per record. The template itself is parsed as a shape, so structure (objects, arrays, nesting) is preserved exactly; only the tokens change.
Placeholders fall into three groups by argument style:
- No arguments
{{name}},{{email}},{{bool}}. Each call returns one fresh value from a built-in source.- Numeric range
{{int 1 100}}returns a whole number where 1 \le n \le 100.{{float 0 1}}returns a decimal in the same closed interval.- Explicit choice
{{pick red|green|blue}}returns one option chosen uniformly from the pipe-separated list.
The rule that turns a string into a number or boolean is strict: the placeholder must be the entire string. "{{int 1 100}}" becomes the number 57. But "score: {{int 1 100}}" stays the string "score: 57", because the token is only part of the text.
The math behind the random values
Each numeric or choice placeholder draws from a uniform distribution. For {{int a b}} every integer from a to b is equally likely. The count of possible values is:
Here a is the lower bound, b is the upper bound, and N is how many distinct integers can appear. For {{int 1 100}} that gives N = 100 - 1 + 1 = 100, so each value has probability 1/100 = 0.01.
The expected mean of many draws sits at the midpoint:
For {{int 1 100}} the expected mean is \mu = (1 + 100)/2 = 50.5. Generate 10,000 records and the average of the id field should land near 50.5, usually within a fraction of a point.
The same uniform logic applies to {{pick red|green|blue}}: with 3 options, each color has probability 1/3 \approx 0.3333. Over 3,000 records you expect roughly 1,000 of each, though random variation of a few dozen either way is normal.
A worked example reproducing the demo
Expanding the default template into 5 records
Load the tool and press the demo button. It uses a template close to this:
{"id": "{{int 1 1000}}", "name": "{{name}}", "email": "{{email}}", "role": "{{pick admin|editor|viewer}}", "active": "{{bool}}", "score": "{{float 0 100}}"}
- The parser reads the template as one object with six keys. Structure is fixed; only the placeholder tokens will vary.
- For each of the 5 records it calls each generator once.
{{int 1 1000}}draws an integer, so probability per value is 1/1000 = 0.001. {{pick admin|editor|viewer}}has 3 options, each with probability 1/3 \approx 0.3333. Across 5 records you often see a repeat; that is expected, not a bug.- Because
id,activeandscoreare each a lone placeholder, they emit a number, a boolean and a number.name,emailandrolestay strings.
A plausible result:
[{"id": 412, "name": "Sofia Rossi", "email": "[email protected]", "role": "editor", "active": true, "score": 73.4}, ... four more ...]
Reading and checking the output
Two quick checks tell you the output is sound. First, is it valid JSON? A stray comma or an unbalanced brace in your template propagates into every record. Paste the result into the JSON Formatter & Validator to confirm it parses and to query it with JSONPath.
Second, do the types match what your consumer expects? If your code reads record.score as a number, make sure the template writes "{{float 0 100}}" as a lone placeholder so it emits 73.4, not the string "73.4". A type mismatch here is the single most common cause of a mock that "looks right" but breaks the client.
Generate a small batch first (5 records), eyeball the types and structure, then scale to the count you actually need. Fixing a template bug at 5 records is cheaper than finding it at 5,000.
Common mistakes
The pitfalls below account for most broken mocks.
- Expecting a number but wrapping the placeholder in text.
"user-{{int 1 100}}"is a string by design. If you needed the number, remove the prefix. - Assuming uniqueness.
{{int 1 1000}}can repeat. Across 1,000 records the chance of at least one collision is near certainty (the birthday problem). Ifidmust be unique, do not rely on a small random range. - Mismatched bounds. Writing
{{int 100 1}}with the larger number first gives an empty or undefined range. Always put the lower bound first. - Trailing commas in the template. JSON does not allow them. One trailing comma makes the whole batch fail to parse.
- Treating fake data as safe to publish. A generated name might, by chance, match a real person. Never present it as anonymized real data.
Related tools
Once you have a batch of mock records, these tools handle the next step:
- Validate and query the output with the JSON Formatter & Validator.
- Convert a batch to CSV, YAML, TOML or XML with the data converter.
- Check that your mock matches a contract using the JSON Schema Validator.
- Compare two generated batches with JSON Diff.
- If your template feeds a config file, lint it with the YAML Linter.
- Build a regex to spot-check field formats in the Regex Tester, and escape awkward string values with the String Escaper.
Frequently asked questions
Why did my number come out as a string?
Because the placeholder was not the only content of the string. "{{int 1 100}}" becomes the number 57, but "id: {{int 1 100}}" stays the string "id: 57". Remove any surrounding text to get a real number.
Are the random values guaranteed unique?
No. Each draw is independent and can repeat. For {{int 1 1000}} across 1,000 records, at least one duplicate is almost certain. Use a wide range or a dedicated sequence if you need unique IDs.
Does my data get sent anywhere?
No. Generation runs entirely in your browser. Nothing you paste leaves your device.
How many records can I generate?
You choose the count. Very large counts (tens of thousands) build a big in-memory array, so watch browser memory. For flat, column-style datasets, the Test Data Generator in Data & Files is often a better fit.
Can I nest placeholders inside arrays and objects?
Yes. The template is parsed as a full JSON shape, so a placeholder inside a nested object or an array element expands the same way as one at the top level.