ToolSura
    ToolSura
    HomeTools
    Blog
    ToolSura
    ToolSuraPrivacy-First Tools

    Free utilities that run in your browser. No trackers, no accounts, no uploads.

    All Systems Operational

    Product

    • Free Online Tools
    • Contact
    • FAQs
    • About

    Legal

    • Privacy Policy
    • Cookie Policy
    • Terms & Conditions
    • Disclaimer

    Resources

    • Blog
    • Brand
    • Help

    Social Links

    • Bluesky
    • Mastodon
    • X
    • Product Hunt
    • GitHub
    • LinkedIn
    • DEV.to
    • YouTube

    © 2026 ToolSura. Free tools that run in your browser.

    Remote-First / Based in India

    Technical Manifesto

    Private • Client-Side • No Uploads

    ToolSura on Nick Launches
    Browser-Native
    Privacy-First
    Skip to main content
    Toolsura
    developer-tools
    C
    Chloe Bertrand

    Generating JSON Schema from code, data or models

    August 8, 2026 · 11 min read

    Compare JSON Schema generation — code-first (Zod, Valibot), data-first (quicktype), model-first. Covers validation, CI/CD, migration.

    JSON Schema code beside a node diagram and a checklist reading Validate, Auto-complete, Schema Preview, Error Detection
    JSON Schema code beside a node diagram and a checklist reading Validate, Auto-complete, Schema Preview, Error Detection

    A JSON schema generator turns your types, data, or models into machine-readable contracts that power validation, documentation, and code generation across your stack. In 2025, the ecosystem has consolidated around TypeScript-first libraries like Zod and Valibot. They emit JSON Schema as a byproduct of type-safe development, a shift from the manual schema-authoring that dominated a few years ago.

    The JSON Schema specification now sees over 60 million weekly downloads across its tooling, with 5,000+ members in the official community Slack (1). Whether you are building API contracts, validating incoming payloads, or generating types from existing schemas, choosing the right generation approach saves hours of maintenance and prevents runtime surprises.

    This guide covers the four generation approaches, compares the leading tools, shows CI/CD integration patterns, and provides a migration checklist for Draft 2020-12, the current stable specification (2).

    What is a JSON schema generator?

    JSON Schema is a vocabulary for annotating and validating JSON documents. It defines the structure, constraints, and semantics of JSON data, from simple type checks to complex conditional validation. The specification evolved from Draft 4 (2013) through Draft 7 (2017) and Draft 2019-09 to the current Draft 2020-12 (2). Each iteration added features like unevaluatedProperties, recursive $ref support via $defs, and improved format validation.

    A JSON Schema is itself a JSON document that describes what valid JSON looks like. A schema for a user object might specify required fields, string formats such as email and UUID, numeric ranges, and array constraints. This self-describing nature makes JSON Schema ideal for API contracts, configuration validation, and cross-language interoperability.

    Key concepts

    Keywords are the building blocks: type, properties, required, enum, const, allOf/anyOf/oneOf/not, and if/then/else for conditional logic. The 2020-12 draft added unevaluatedProperties and unevaluatedItems. References ($ref) enable reuse and recursion, essential for tree structures and polymorphic types. Formats extend validation beyond JSON's primitive types: date-time, email, uuid, uri, and custom regex via pattern.

    Draft progression matters because tool support varies. Draft 4 and 7 remain common in legacy tooling. Draft 2020-12 standardized $defs over definitions and made format assertive by default. Always declare $schema: "https://json-schema.org/draft/2020-12/schema" in your schemas to signal intent.

    Why JSON Schema generation matters in 2025

    Three forces drive adoption: mature TypeScript-first schema libraries, the standardization of Draft 2020-12, and the operational need for runtime validation that matches compile-time types. The JSON Schema tools directory lists over 50 tools across code-to-schema, data-to-schema, model-to-schema, and schema-to-code categories (3).

    TypeScript-first libraries like Zod and Valibot have become the primary way developers generate JSON Schema (4). Instead of writing schemas by hand and separately maintaining TypeScript interfaces, you define validation logic once and get both runtime validation and JSON Schema export. This single-source-of-truth approach eliminates drift between types and validators. For a deeper look at the compile-time side of this story, see our TypeScript type safety guide.

    The convergence matters practically. AJV, the most widely adopted validator, compiles schemas to optimized JavaScript functions and powers validation in ESLint, webpack, Fastify, and 30+ other projects (5). When your generator emits standard-compliant Draft 2020-12, you inherit this entire validation stack.

    The drift problem

    Before code-first generation, teams maintained parallel artifacts: TypeScript interfaces for compile-time safety and JSON Schema files for runtime validation. These inevitably diverged. A field was renamed in TypeScript but not in the schema, or an optional field was added to one but not the other. Code-first eliminates this class of bug by making the schema a derived artifact.

    How JSON Schema generation works: four approaches

    1. Code-first: TypeScript types to JSON Schema

    Define your data model in Zod, Valibot, or ArkType, then export to JSON Schema. This is the recommended approach for new TypeScript projects.

    import { z } from "zod";
    
    const UserSchema = z.object({
      id: z.string().uuid(),
      email: z.string().email(),
      name: z.string().min(1).max(100),
      roles: z.array(z.enum(["admin", "user", "viewer"])),
      createdAt: z.string().datetime(),
    });
    
    // Export to JSON Schema Draft 2020-12
    const jsonSchema = z.toJSONSchema(UserSchema, {
      target: "draft-2020-12",
      unrepresentable: "throw",
      cycles: "ref",
      reused: "ref",
    });
    

    Zod handles recursive types via z.lazy() and maps enums to JSON Schema enum. The unrepresentable option controls how Zod-specific types like bigint, Date, and transforms are handled: "throw" fails fast, "any" emits an empty schema.

    Valibot offers an equivalent functional API with a smaller bundle, roughly 5KB versus Zod's 12KB, which makes it attractive for edge functions and client bundles. The @valibot/to-json-schema package emits Draft 2020-12 by default. ArkType provides the most aggressive type inference of the three, using a string-based DSL such as "string >= 1 & <= 100" for constrained fields, and exports schemas via toJSONSchema().

    2. Data-first: JSON samples to inferred schema

    When you have JSON payloads but no types, such as legacy APIs, third-party webhooks, or log data, tools like quicktype reverse-engineer a schema (7):

    quicktype --lang schema --input sample.json --output inferred.schema.json
    

    Format and inspect your samples with the ToolSura JSON formatter before inference so malformed payloads do not poison the result. Inference works well for exploration. It produces verbose schemas with loose constraints, treating everything as optional and typing strings widely. Treat inferred schemas as starting points and refine them manually or layer Zod validation on top.

    Inference has real limits: no semantic understanding of email versus plain string, no required-field detection, no enum detection from single samples. Feed multiple samples to improve accuracy.

    3. Model-first: Protobuf, OpenAPI, and SQL to JSON Schema

    Existing IDLs and database schemas can generate JSON Schema:

    • Protocol Buffers: protoc-gen-jsonschema converts .proto files
    • OpenAPI 3.0: openapi-to-json-schema extracts component schemas
    • SQL: ORM-aware generators like Prisma and Drizzle emit JSON Schema from table definitions

    This approach shines when JSON Schema is a downstream artifact of an existing source of truth.

    4. Manual authoring

    Hand-writing schemas still makes sense for simple one-off contracts, for advanced keywords that generators do not expose, such as custom format, contentMediaType, and contentEncoding, or when the schema itself is the public contract that consumers depend on.

    Deep comparison: generation tools

    Tool Approach Best For Draft Support Bundle Size
    Zod Code-first New TS projects, single source of truth 2020-12, 7, 4, OpenAPI 3.0 ~12 KB
    Valibot Code-first Bundle-sensitive apps 2020-12, 7 ~5 KB
    ArkType Code-first Maximum type inference 2020-12 ~15 KB
    Effect Schema Code-first Effect ecosystem 2020-12 ~20 KB
    json-schema-to-typescript Schema to Types Existing schemas, polyglot teams Reads any draft CLI only
    quicktype Data-first Legacy API exploration Emits Draft 7 CLI only
    Pydantic Code-first Python backends, FastAPI 2020-12 via model_json_schema() N/A

    Decision framework:

    • New TypeScript project: Zod for maturity and DX, or Valibot for bundle size
    • Complex inference requirements: ArkType
    • Effect ecosystem: Effect Schema
    • Existing JSON Schema files: json-schema-to-typescript (6)
    • Unknown JSON payloads: quicktype, then refine
    • Python backend: Pydantic
    • Multi-language monorepo: define in one language, generate JSON Schema, consume it elsewhere via json-schema-to-typescript

    Validation: AJV integration and CI/CD patterns

    AJV (Another JSON Schema Validator) remains the performance benchmark. It compiles schemas to JavaScript functions, achieving 10-100x speedups over interpreted validators on repeated validation. JSON Schema spec lead Ben Hutton calls AJV "the implementation of choice" (5).

    import Ajv from "ajv";
    import draft202012 from "ajv/dist/draft202012.js";
    
    const ajv = new Ajv({ strict: true, draft: draft202012 });
    const validate = ajv.compile(jsonSchema);
    
    if (!validate(req.body)) {
      return res.status(400).json({ errors: validate.errors });
    }
    

    AJV supports async custom formats, such as checking that an email exists in your database, and custom keywords for domain rules, such as requiresRole checks on role arrays. For a browser-native alternative without compilation overhead, Hyperjump provides a spec-compliant interpreted validator that passes the official test suite.

    You can paste any generated schema along with a test payload into the ToolSura JSON validator to catch syntax and semantic errors before wiring it into a pipeline.

    CI/CD pipeline gates

    Add schema validation as a pipeline step so contract drift fails the build. Save this as .github/workflows/schema-validation.yml:

    name: Schema Validation
    on: [push, pull_request]
    jobs:
      validate:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - run: npm ci
          - run: npx ajv compile -s schemas/*.json -d test/fixtures/*.json
          - run: npx ajv validate -s schemas/api-request.schema.json -d test/fixtures/valid-request.json
    

    Validate both the schema syntax (compilation) and representative payloads (validation). Store known-good and known-bad fixtures to catch regressions. The same three ajv commands slot directly into GitLab CI or any other pipeline runner. The open-source Pact contract testing docs cover how schema gates fit into a broader testing strategy.

    Migration: Draft 7 to Draft 2020-12 checklist

    Draft 2020-12 introduces breaking changes. Key migrations:

    1. definitions becomes $defs: rename the keyword and update $ref paths from #/definitions/Foo to #/$defs/Foo
    2. exclusiveMinimum and exclusiveMaximum now accept numbers directly instead of booleans
    3. New keywords: unevaluatedProperties, unevaluatedItems, and contains with minContains/maxContains
    4. $recursiveRef becomes $recursiveAnchor for recursive schemas
    5. format now asserts by default; use format-annotation vocabulary for annotation-only mode

    Draft 7:

    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "definitions": {
        "User": {
          "type": "object",
          "properties": {
            "age": { "type": "integer", "exclusiveMinimum": true, "minimum": 0 }
          }
        }
      }
    }
    

    Draft 2020-12:

    {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "$defs": {
        "User": {
          "type": "object",
          "properties": {
            "age": { "type": "integer", "exclusiveMinimum": 0 }
          }
        }
      }
    }
    

    For bulk migration, json-schema-migrate converts existing files and applies these rules automatically. Run the official JSON Schema Test Suite against your schemas after migration to catch edge cases (8).

    OpenAPI and JSON Schema interoperability

    OpenAPI 3.0 uses an extended JSON Schema called the Schema Object, with additional keywords like discriminator, xml, example, and externalDocs (9). Conversion tools handle the common subset but lose fidelity on several features:

    Feature JSON Schema OpenAPI 3.0 Round-trips?
    type, properties, required Yes Yes Yes
    allOf/anyOf/oneOf Yes Yes Yes
    discriminator No Yes Loses mapping
    callbacks, links, servers, security No Yes No
    example/examples, deprecated Yes (2020-12) Yes Yes

    Discriminator mappings become plain oneOf without runtime dispatch hints, and callbacks have no JSON Schema equivalent at all. For API-first teams, maintain OpenAPI as the source of truth and extract JSON Schema components for validation. Schema-first teams can generate OpenAPI from JSON Schema and then add the OpenAPI-specific metadata by hand.

    The Swagger Editor verifies that converted specs still parse and reference correctly after round-tripping. You can also use Postman to confirm that live endpoints honor the contracts your schemas describe.

    Monorepo schema sharing strategies

    Sharing schemas across packages prevents contract drift:

    1. Private npm package: publish @yourorg/schemas containing the .json files plus .d.ts types generated by json-schema-to-typescript (6)
    2. Version pinning: consumers lock to specific schema versions, so npm ls @yourorg/schemas audits exactly which contract each service runs
    3. Breaking-change detection: run json-schema-diff in the schema package's CI to fail PRs that remove required fields or narrow types
    4. Schema registry: for runtime validation in distributed systems, deploy Apicurio Registry or Confluent Schema Registry, both of which support JSON Schema alongside Avro and Protobuf

    Consumers then import compile-time types and runtime validators from the same artifact:

    import { User } from "@yourorg/schemas/types/user";
    import userSchema from "@yourorg/schemas/schemas/user.schema.json";
    
    const validate = ajv.compile(userSchema);
    

    One package becomes the contract layer for the entire monorepo, and breaking changes surface in CI before any service deploys against them.

    Add structured data to your own schemas

    If you publish schema documentation pages, mark them up with TechArticle JSON-LD so search engines can attribute authors, dates, and publishers correctly:

    {
      "@context": "https://schema.org",
      "@type": "TechArticle",
      "headline": "User API Schema Reference",
      "author": { "@type": "Person", "name": "Jane Developer" },
      "datePublished": "2026-01-15",
      "proficiencyLevel": "Expert"
    }
    

    Related tools and further reading

    • Validate generated schemas against real payloads with the ToolSura JSON validator
    • Format and inspect JSON before inference with the ToolSura JSON formatter
    • Test API endpoints against your schema contracts with Postman
    • Validate OpenAPI specs that reference JSON Schema components with the Swagger Editor
    • JSON Diff Compare
    • JSON Schema Generator
    • Inferring Schemas From JSON Samples — how quicktype derives a schema from data
    • JSON Schema vs TypeScript Types — which layer catches which class of bug

    References

    [1] JSON Schema Official Site — https://json-schema.org/ [2] JSON Schema Specification — https://json-schema.org/specification [3] JSON Schema Tools Directory — https://json-schema.org/tools [4] Zod JSON Schema Conversion — https://zod.dev/json-schema [5] AJV Validator Documentation — https://ajv.js.org/ [6] json-schema-to-typescript — https://github.com/bcherny/json-schema-to-typescript [7] quicktype — https://github.com/glideapps/quicktype [8] JSON Schema Test Suite — https://github.com/json-schema-org/JSON-Schema-Test-Suite [9] OpenAPI 3.0 Specification — https://spec.openapis.org/oas/v3.0.3.html

    Chloe Bertrand

    Written by

    Chloe Bertrand

    I hold one rule for everything on this beat: generated code is still code, and it lands in your repository where somebody has to read it. If you cannot show me what it produced, I cannot recommend the tool. Payload to typed client is the most useful of these. The generator reads a schema or a sample document, infers field types and emits a structure that fails at compile time when a field is missing.

    The limits are honest and worth stating. Types come from the samples provided, so a field seen only as null becomes nullable, and one seen as an integer may arrive as a string from a different endpoint. Generating from a real schema beats generating from a sample every time. SQL to ORM goes the other way and is harder to do well.

    The generator has to guess a data model from query text, and a join between two tables produces a nested structure whose shape depends on assumptions about cardinality. The generated layer is a reasonable starting point and rarely the finished article. Every generated file should carry a header saying so, should be excluded from formatting rules that fight it, and should never be edited by hand.

    Drift between the generator and a hand-edit is the failure mode that costs the most time, because the next regeneration removes the change silently. One security note belongs with the ORM pages. Query builders make the safe path easy, and raw fragments inside them put it back within reach. Every page covering generated query code shows which calls parameterise and which interpolate.

    Share

    Frequently Asked Questions

    PreviousBest Free Online Tools by Task: 2026 Utilities GuideNextHow to Decode a JWT Token Online (Safely, Step by Step)

    Comments

    Leave a Review

    Rate this tool
    Overall Rating
    Spam Protection Active