Skip to content

Latest commit

 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

json-schema-from-sample

npm install @ferrow/json-schema-from-sample

CI

Infer a draft-07 JSON Schema subset from sample JSON data. Strict TypeScript, zero runtime dependencies.

Why

Hand-writing JSON Schema for an API response or config shape is tedious and drifts from reality. This library infers one from real samples — the more samples you provide, the more it can safely say about nullability, required fields, and enums, and it never claims more than the samples support.

Quickstart

import { infer } from "json-schema-from-sample";

const schema = infer([
  { id: "8f14e45f-ceea-467e-b3a3-7a3d3f2f1a10", email: "a@example.com", role: "admin" },
  { id: "9a14e45f-ceea-467e-b3a3-7a3d3f2f1a11", email: "b@example.com", role: "member" },
  // ...
]);

API

infer(samples, options?): RootSchema

Merges observations across all samples into a single schema.

  • options.tupleLengthConstraints (default false) — emit minItems/maxItems when an array field's observed length never varies. Off by default: a few samples can't prove a length rule.
  • options.enumMaxDistinct (default 5) — max distinct string values for enum detection.
  • options.enumMinSamples (default 10) — min sample count before enum detection runs.

Inference rules

  • Types: merged as a union across samples (e.g. ["null", "string"]); integer + float observed together widen to "number".
  • Nullable: a field observed as null in some samples and a value in others gets "null" added to its type.
  • Required: a property present in every sample that reached that object is marked required.
  • Enum: string fields with ≤enumMaxDistinct distinct values across ≥enumMinSamples samples.
  • Format: date-time, email, uuid, uri detected via regex when all observed strings at that field match.
  • Arrays: item schema is inferred by merging every element across every array observed at that path.

Limits

  • Samples-only inference — it cannot prove constraints samples don't demonstrate (numeric ranges, string length bounds, exact tuple shapes). tupleLengthConstraints is opt-in for that reason.
  • Format detection requires unanimous agreement across all observed strings at a field; mixed-format fields get no format.
  • No $ref, oneOf/anyOf, or schema composition beyond simple type unions — this targets the common 80% case, not the full draft-07 spec.

Part of the ferrow-toolkit collection · Sponsored by Ferrow

About

Infer a draft-07 JSON Schema subset from sample data: types, nullable, required, enum, format detection. Zero deps.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages