Skip to content

Library comparisons

Capability matrix across the validators, codecs, and ontology tools most often compared to json-tology. Rows are concrete features; each cell is Yes / Limited / No / N/A with a one-line note where the answer needs context.

For runnable performance numbers see Benchmarks. For inline side-by-side code samples on individual methods, every reference page (under Validation, Composition, Transforms, Registry, etc.) includes a code-group showing the equivalent code in each peer library where supported.

Methodology. Cells reflect each library's current public API as of 2026-05. Where a library can express a concept indirectly (e.g. is-style guards in plain TS), the cell says Limited with a note. N/A means the feature is structurally out of scope for that library (Pydantic is Python-only, AJV is JS-only, etc.).

Authoring & type inference

Capabilityjson-tologyZodValibotTypeBoxAJVPydanticYupJoiio-tsEffect SchemaArkTypeRuntypes
Authoring languageJSON SchemaTS DSLTS pipe DSLTS DSL → JSON SchemaJSON SchemaPython classesTS DSLJS DSLTS combinatorsTS combinatorsTS string DSLTS combinators
Static T = Infer<schema>YesYesYesYesNoN/A (runtime classes)YesLimited (typings)YesYesYesYes
Compile-time $ref resolutionYesNoNoLimitedNoN/ANoNoLimitedLimitedNoNo
Compile-time duplicate-$id checkYesN/AN/ANoNoN/AN/AN/ANoNoN/ANo
Editor "go to definition" on $idYesYes (variable)Yes (variable)YesNoYesYes (variable)NoYesYesLimitedYes

JSON Schema interop

Capabilityjson-tologyZodValibotTypeBoxAJVPydanticYupJoiio-tsEffect SchemaArkTypeRuntypes
Authored as JSON SchemaYesNoNoYesYesNoNoNoNoNoNoNo
Export to JSON SchemaYesLimited (3rd-party)Limited (@valibot/to-json-schema)Yes (identity)Yes (identity)Yes (model_json_schema())Limited (3rd-party)NoNoYes (@effect/schema/JSONSchema)YesNo
Import existing JSON SchemaYesNoNoLimitedYesLimited (TypeAdapter)NoNoNoNoNoNo
Draft 2020-12YesN/AN/ALimitedYesLimitedN/AN/AN/ALimitedN/AN/A
$ref between schemasYesNoNoLimitedYesLimitedNoNoNoNoNoNo
Custom keywordsYes (vocab plugins)NoNoLimitedYesLimitedNoNoNoNoNoNo

Runtime validation

Capabilityjson-tologyZodValibotTypeBoxAJVPydanticYupJoiio-tsEffect SchemaArkTypeRuntypes
Validate (errors only)Yes (validate)Yes (safeParse)Yes (safeParse)Yes (Check/Errors)YesYesYesYesYes (decode)YesYesYes (check)
Parse / instantiate (throw on fail)Yes (instantiate)Yes (parse)Yes (parse)Yes (Decode)No (validate only)Yes (model_validate)Yes (validate)Yes (validateAsync)YesYes (decode)YesYes (parse)
Type guard / predicateYes (is)LimitedYes (is)Yes (Check)NoNoNoNoYes (is)Yes (is)Yes (assert/allows)Yes (guard)
All-errors modeYesYesYesYesYesYesYesYesYesYesYesLimited
Async validatorsLimitedLimited (refine w/ async)Yes (asyncParse)NoLimitedYes (@field_validator)YesYes (validateAsync)LimitedYes (Effect)NoNo
Compiled validators (codegen)Limited (graph cache)NoNoLimited (compile)Yes (codegen)NoNoNoNoNoNoNo

Coercion & transforms

Capabilityjson-tologyZodValibotTypeBoxAJVPydanticYupJoiio-tsEffect SchemaArkTypeRuntypes
String → number/boolean castYes (cast / enableTypeCast)Yes (z.coerce.*)Yes (coerce)LimitedNoYesYesYesNoYesLimitedNo
Strip unknown keysYes (clean)Yes (.strip())Yes (strip*)NoNoYes (extra='ignore')Yes (.noUnknown())Yes (.unknown(false))NoYesNoNo
Decode → typed value (codec)Yes (Transform)Yes (.transform())Yes (transform)LimitedNoYes (validators)Yes (.transform())Yes (custom)Yes (Type<A, O, I>)Yes (codec-first)NoNo
Encode → wire format (codec)Yes (Transform.encode / dump)LimitedLimitedLimitedNoYes (model_dump)NoNoYesYesNoNo
Branded / nominal typesYes (constraint brands)Yes (z.brand)Yes (brand)YesNoNoNoNoYesYesYesYes
Default valuesYesYes (.default())Yes (optional w/ default)YesYesYesYesYesLimitedYesYesLimited
Computed propertiesYes (addComputed)Limited (.transform())LimitedNoNoYes (@computed_field)NoNoNoYesNoNo

Composition

Capabilityjson-tologyZodValibotTypeBoxAJVPydanticYupJoiio-tsEffect SchemaArkTypeRuntypes
Extend / mergeYes (Compose.extend)Yes (.extend())Yes (merge)Yes (Intersect)Yes (allOf)Yes (inherit)Yes (.concat())Yes (.concat())Yes (intersection)YesYesYes
Pick / omitYesYesYesYes (Pick/Omit)NoYes (model_fields)Yes (.pick/.omit)NoNoYesYesYes
Partial / requiredYesYes (.partial())Yes (partial)Yes (Partial)NoYesYes (.partial)NoNoYesYesYes
IntersectionYesYes (.and())Yes (intersect)Yes (Intersect)Yes (allOf)N/ANoNoYesYesYes (&)Yes
Discriminated unionYesYes (.discriminatedUnion)Yes (variant)Yes (Union + tag)Yes (oneOf + discriminator)Yes (Union + tag)NoNoYes (taggedUnion)YesYesYes
Structural equivalence detectionYes (findDuplicates)NoNoNoNoNoNoNoNoNoNoNo

Ontology & RDF

Capabilityjson-tologyZodValibotTypeBoxAJVPydanticYupJoiio-tsEffect SchemaArkTypeRuntypes
Canonical graph representationYesNoNoNoNoNoNoNoNoNoNoNo
OWL TBox emissionYes (toTbox)NoNoNoNoNoNoNoNoNoNoNo
SHACL shape emissionYes (toShacl)NoNoNoNoNoNoNoNoNoNoNo
RDF quad round-tripYes (toQuads/fromQuads)NoNoNoNoNoNoNoNoNoNoNo
owl:sameAs / ABox identityYesNoNoNoNoNoNoNoNoNoNoNo
Schema visualizationYes (Cytoscape via viz)Limited (3rd-party)NoNoLimitedNoNoNoNoNoNoNo

Runtime & platform

Capabilityjson-tologyZodValibotTypeBoxAJVPydanticYupJoiio-tsEffect SchemaArkTypeRuntypes
Browser runtimeYesYesYesYesYes (bundle)No (Python)YesLimitedYesYesYesYes
Node ≥ 24YesYesYesYesYesN/AYesYesYesYesYesYes
Bun / DenoYesYesYesYesYesN/AYesLimitedYesYesYesYes
Tree-shakableLimitedLimitedYesYesLimitedN/AYesNoYesLimitedYesYes
Zero runtime dependenciesLimited (commander for CLI only)YesYesYesNoN/ANoNoYesNo (Effect runtime)YesYes
TypeScript strict-mode cleanYesYesYesYesLimitedN/ALimitedLimitedYesYesYesYes
Federated / dynamic schema loadingYes (prefetch + snapshot)NoNoNoYes (loadSchema)Limited (TypeAdapter)NoNoNoNoNoNo

When to reach for each

  • json-tology: your schemas need to act as both a TypeScript type source and a knowledge graph (OWL/SHACL/RDF). You author in JSON Schema once and project from there.
  • Zod: pure runtime validation with first-class TS inference and a friendly DSL. The default choice for TS-first apps with no graph requirements.
  • Valibot: same niche as Zod but tree-shakable and roughly 10× smaller bundle on minimal use.
  • TypeBox: you want JSON Schema as the canonical artifact but author in a TS-typed DSL. The closest comparator to json-tology on the schema-as-output axis.
  • AJV: pure JSON Schema validation, no TS inference, fastest in cold-path validation throughput. Pair with TypeBox for typed authoring.
  • Pydantic: Python. Sets the bar for type-first runtime validation in the Python ecosystem; cross-language reference.
  • Yup / Joi: older DSL-first validators; common in legacy forms / web APIs. Yup is TS-friendly; Joi is JS-first.
  • io-ts: pure functional codec library. Decoder/encoder symmetry is its strength; fp-ts integration is its tax.
  • Effect Schema: codec library inside the Effect ecosystem. Strong when the rest of the app already uses Effect; heavy import otherwise.
  • ArkType: DSL is a string with TS-typed grammar (literal-types magic). Speed-competitive; novel ergonomics.
  • Runtypes: combinator library. Smaller and simpler than io-ts; less capable codec story.

See also

Released under the MIT License.