schema-components - v3.7.0
    Preparing search index...

    schema-components - v3.7.0

    schema-components

    GitHub npm version License: MIT GitHub Workflow Status API reference Storybook

    React components that render UI from Zod schemas, JSON Schema, and OpenAPI documents.

    Define your data model once. Get presentational views, input fields, and editable forms — no manual wiring.

    npm install schema-components
    

    Peer dependencies: zod@^4.0.0, react@^18.0.0 || ^19.0.0.

    schema-components requires Zod 4. If you are on Zod 3, see the Zod 4 migration guide. If a Zod 3 schema is passed (detected via _def.typeName), a descriptive SchemaNormalisationError is raised pointing at the Zod 4 migration guide. Schemas from other Standard Schema libraries are not currently supported.

    import { z } from "zod";
    import { SchemaComponent } from "schema-components/react/SchemaComponent";

    const userSchema = z.object({
    name: z.string().min(1).meta({ description: "Full name" }),
    email: z.email().meta({ description: "Email address" }),
    role: z.enum(["admin", "editor", "viewer"]).meta({ description: "Role" }),
    active: z.boolean().meta({ description: "Active" }),
    });

    function UserCard() {
    const [user, setUser] = useState({
    name: "Ada Lovelace",
    email: "ada@example.com",
    role: "admin",
    active: true,
    });

    return (
    <SchemaComponent
    schema={userSchema}
    value={user}
    onChange={setUser}
    />
    );
    }

    Renders every field as an editable input. Add readOnly to the component for a read-only view:

    <SchemaComponent schema={userSchema} value={user} readOnly />
    
    %%{init:{"theme":"dark"}}%% flowchart LR Zod["Zod schema"] -- "z.toJSONSchema()" --> JS["JSON Schema"] JSONIn["JSON Schema input"] --> JS OAS["OpenAPI doc"] -- "extract schemas" --> JS JS -- "walker" --> React["React"]
    %%{init:{"theme":"default"}}%% flowchart LR Zod["Zod schema"] -- "z.toJSONSchema()" --> JS["JSON Schema"] JSONIn["JSON Schema input"] --> JS OAS["OpenAPI doc"] -- "extract schemas" --> JS JS -- "walker" --> React["React"]
    flowchart LR
      Zod["Zod schema"] -- "z.toJSONSchema()" --> JS["JSON Schema"]
      JSONIn["JSON Schema input"] --> JS
      OAS["OpenAPI doc"] -- "extract schemas" --> JS
      JS -- "walker" --> React["React"]

    One walker, one input format. The walker reads standard JSON Schema keywords (Draft 2020-12) — decoupled from Zod's internal API. z.toJSONSchema() is lossless: it preserves readOnly, writeOnly, custom .meta() properties, constraints, formats, and defaults.

    z.fromJSONSchema() is used only for validation — converting JSON Schema / OpenAPI inputs back to Zod when validate is true and the original wasn't a Zod schema.

    Spec Support
    JSON Schema Draft 04 / 06 / 07 / 2019-09 / 2020-12 All supported; older drafts normalised to Draft 2020-12
    OpenAPI 2.0 (Swagger) Full document restructure to OpenAPI 3.1
    OpenAPI 3.0.x nullable, discriminator, example normalised
    OpenAPI 3.1.x Native; webhooks and components/pathItems resolved

    See packages/core/README.md for the full keyword matrix and documented type-level fallbacks.

    <SchemaComponent> auto-detects the input format:

    // Zod schema
    <SchemaComponent schema={z.object({ name: z.string() })} value={data} />

    // JSON Schema
    <SchemaComponent
    schema={{ type: "object", properties: { name: { type: "string" } } }}
    value={data}
    />

    // OpenAPI document + schemaRef
    <SchemaComponent
    schema={openApiSpec}
    schemaRef="#/components/schemas/User"
    value={data}
    />

    Render API operations with type-safe field overrides:

    import { ApiOperation } from "schema-components/openapi/components";

    // Full operation — parameters, request body, responses
    <ApiOperation schema={petStore} path="/pets" method="post" />

    // Just the request body with type-safe fields
    <ApiRequestBody
    schema={petStore}
    path="/pets"
    method="post"
    fields={{
    name: { description: "Pet name" }, // ✓ inferred from as const
    }}
    />

    Headless by default (plain HTML). Wrap with a theme adapter for styled components:

    import { SchemaProvider } from "schema-components/react/SchemaComponent";
    import { shadcnResolver } from "schema-components/themes/shadcn";

    <SchemaProvider resolver={shadcnResolver}>
    <SchemaComponent schema={userSchema} value={user} onChange={setUser} />
    </SchemaProvider>
    import { renderToHtml } from "schema-components/html/renderToHtml";

    const html = renderToHtml(userSchema, {
    value: { name: "Ada Lovelace", email: "ada@example.com", role: "admin" },
    readOnly: true,
    });
    import { SchemaView } from "schema-components/react/SchemaView";

    export default async function Page() {
    const user = await getUser();
    return <SchemaView schema={userSchema} value={user} />;
    }

    Every module is imported directly — no barrel files. Organised exports:

    schema-components/core/*         # Walker, types, guards, errors, resolver
    schema-components/react/* # SchemaComponent, SchemaView, SchemaErrorBoundary, headless
    schema-components/openapi/* # Parser, ApiOperation, ApiParameters, etc.
    schema-components/html/* # renderToHtml, renderToHtmlChunks, h() builder, styles
    schema-components/themes/* # shadcn, MUI, custom adapters
    schema-components/styles.css # Default stylesheet for HTML output

    Package Description
    packages/core Published as schema-components on npm — the component library
    packages/docs Storybook documentation site — not published
    pnpm install            # Install all workspace dependencies
    pnpm build # Build the core library
    pnpm check # Typecheck + lint + build
    pnpm test # Run unit tests
    pnpm test:coverage # Run tests with coverage
    pnpm storybook # Start Storybook dev server
    pnpm build-storybook # Build static Storybook site
    pnpm typedoc # Generate TypeDoc API reference

    Published to GitHub Pages on every push to main:

    Surface URL
    API reference (TypeDoc) https://mearman.github.io/schema-components/
    Storybook https://mearman.github.io/schema-components/storybook/