JSON to TypeScript, Zod, JSON Schema, and mock data inference.
Runs entirely in your browser. Paste JSON, get instant types.
Created by Bilal Malik
Follow on Github bilalmlkdev
Every project with an undocumented or loosely-typed API ends up with
someone manually typing out interface Response { ... } by eye. Schemarize
does that inference for you, and goes one step further than most
JSON-to-TS tools:
- Merges multiple samples - paste an array of API responses and it
correctly figures out which fields are always present vs. sometimes
missing (
optional) vs. sometimesnull(nullable), instead of just reading the first object. - Detects enums - a field that only ever takes on a small, repeated
set of string values (e.g.
status: "pending" | "active" | "done") is inferred as a literal union /z.enum, not genericstring. - Detects common string formats - email, URL, UUID, ISO date/datetime
- and generates the matching Zod validator (
z.string().email(), etc.), not justz.string()for everything.
- and generates the matching Zod validator (
- Generates realistic mock data, not
"string"and123placeholders- field names like
email,name,price,avatarUrlget contextually appropriate fake values.
- field names like
- Also generates JSON Schema, for consuming tools that don't speak TypeScript or Zod.
- Upload or drag-and-drop a
.jsonfile, not just paste. - Shareable links - every input/root-name combination can be copied as a URL that reproduces the exact same output for whoever opens it.
- Persists your input in
localStorage, so a refresh doesn't lose your work.
Nothing you paste is sent anywhere - all inference and generation runs client-side.
src/lib/infer.ts- the core engine. Walks a parsed JSON value and builds a structuralInferredTypetree (string/number/boolean/null/ array/object/union/literal). When the top-level input is an array of objects, each element is treated as a separate sample and merged field-by-field, which is how optional/nullable/enum detection works. A field is only inferred as an enum (literal) when it repeats a small set of values across more than one sample - a field where every sample just happens to differ (likeid) is correctly left asstring.src/lib/toTypescript.ts- walks theInferredTypetree and emitsinterfacedeclarations, generating one named interface per nested object.src/lib/toZod.ts- same tree, emitsz.object({...})schemas. Nested schemas are emitted before the schema that references them (Zodconsts aren't hoisted, so declaration order matters - this is a real runtime concern, not just style, and is covered by an integration test that actually imports and runs the generated code).src/lib/toJsonSchema.ts- same tree, emits a draft-07 JSON Schema document.src/lib/toMock.ts- walks the tree and generates a plausible value per field, using field-name heuristics (a field calledemailgets a fake email,pricegets a plausible number, etc.) layered on top of format-based generation for unnamed contexts (array items).
src/lib/infer.test.ts covers the merge engine's trickiest logic:
optional/nullable detection, empty-array handling, union collapsing, and
enum detection (including the false-positive guard for unique-per-record
fields).
src/lib/toZod.integration.test.ts writes generated Zod code to a real
temp file, dynamically imports it, and calls .parse()/.safeParse() on
it - the same manual verification method used during initial development,
now automated so future changes to infer.ts or toZod.ts can't silently
reintroduce the declaration-order bug.
src/
lib/
infer.ts type inference + sample merging (the core engine)
infer.test.ts unit tests for the merge engine
toTypescript.ts TypeScript interface generator
toZod.ts Zod schema generator
toZod.integration.test.ts executes generated Zod code against real zod
toJsonSchema.ts JSON Schema generator
toMock.ts mock data generator
examples.ts built-in example JSON samples
useTheme.ts light/dark/system theme hook
usePersistedInput.ts localStorage + shareable-link persistence
components/
InputPanel.tsx JSON textarea + root name field + examples + file upload
OutputPanel.tsx tabbed output (TypeScript / Zod / JSON Schema / Mock)
CodeBlock.tsx lightweight syntax highlighting
CopyButton.tsx
ShareButton.tsx
ThemeToggle.tsx
Header.tsx
Footer.tsx
React 19 · TypeScript · Vite 8 · Tailwind CSS v4 · lucide-react · Vitest
No runtime dependency on Zod itself in the app bundle - the app only
generates Zod code as text for you to use in your own project. zod is
a devDependency used solely by the integration test to execute generated
output.
Still open, roughly in the order they'd be worth picking up next:
- CLI companion (
npx schemarize data.json --format=zod), matching the pattern used by a sibling project, Hookstash. - More output formats - GraphQL SDL, Go structs, Python
dataclasses/Pydantic, Rust structs. The architecture (walk the same
InferredTypetree) already supports this cleanly. - Virtualized output rendering for very large pasted JSON (10k+ lines), since the code view isn't currently paginated/virtualized.
- Deeply mixed arrays (e.g. an array mixing strings and objects at the top level) fall back to a generic union and haven't been extensively tested against weird real-world API shapes.
This project is licensed under the MIT License.
MIT License
Copyright (c) 2026 Bilal Malik
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
