Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Version 1.0.28#1384

Merged
sinclairzx81 merged 1 commit into
mainfrom
remove
Oct 5, 2025
Merged

Version 1.0.28#1384
sinclairzx81 merged 1 commit into
mainfrom
remove

Conversation

@sinclairzx81

@sinclairzx81 sinclairzx81 commented Oct 5, 2025

Copy link
Copy Markdown
Owner

This PR drops support for Standard Schema and reverts to providing an implementation via an example adapter.


Rationale

TypeBox is a JSON Schema builder and validation compiler. Standard Schema is a set of TypeScript interfaces for Zod-likes.

Internal support for Standard Schema was attempted but proven to complicate TypeBox’s internal composition, inference and validation mechanisms when trying to interpret Standard Schema as a Schema.

Continued support for "Standard Schema Embedding" was deemed unlikely to sit well with longer term goals related to JSON Schema compliance, and where adoption was leading to excessive complexity for little to no benefit to TypeBox. In addition, the specification was observed to cause complications for framework integrators (particularly OpenAPI frameworks that require Json Schema support) and in many cases, specification adoption put TypeBox at odds with the infrastructure it was designed for.

Primary Considerations

  • TypeScript interfaces are neither standards nor schematics, and the terminology used by Standard Schema is at odds with its purpose. A more accurate name for the spec would have been "Standard Validator". One can only speculate at the reasons why one would decide to call a TypeScript validation interface a "Schema".

  • A compiled TypeBox type is not a schema; it is a compiled validator. Implementing Standard Schema on a compiled validator would force TypeBox to blur the distinction between schema and validator from a conceptual standpoint.

  • Standard Schema is designed for Zod-likes that couple schematics to validation. TypeBox is decoupled by design and intended for compatibility with Json Schema compliant validators. TypeBox's design renders Standard Schema fundamentally incompatible because it would force TypeBox to couple schematics to validation.

  • The Standard Schema specification seeks improved DX for Zod-likes by hiding explicit compile or binding calls (e.g. adapters) to framework interfaces, but hinders integration for everything else. Libraries that make the principled decision to decouple schematics from validation (such as TypeBox) are made to suffer diminished DX even in situations where the library would otherwise be natively supported.

  • Irrespective of the diminished DX involved with wrapping TB types (via Compile), the general observation has been that naive adoption of Standard Schema (on the principle it is a Schema) is forcing implementation patterns that run contrary to best practice software design and can (in some cases) lead to undue complexity for the hosting framework (notable for JSON Schema dependent systems)

Historical

TypeBox was written specifically to break away from the problems resulting from coupled validator design (specifically Joi, Yup, circa 2017). This was based on the observation that while these libraries provided immense value with regard to schema construction, most of the time I needed to transform them to JSON Schema in order to be used in production infrastructure (performance, interoperability, security). TypeBox was motivated in response to transform tooling producing schematics with validation behaviors that differed from the source library, resulting in data-integrity hazards.

TypeBox is written to promote sound system design by encouraging infrastructure to embrace cross-language, interoperable schematics for data representation. The TypeBox view (my view) is that libraries should emit JSON Schema (or other specification) so that trusted, secure, and high-performance validators (such as Ajv) can enforce data validation constraints consistently across languages and network boundaries.

Attempts to Integrate Standard Schema

In TBV1, attempts were made to try and integrate Standard Schema as a sub schema of JSON Schema. This would have enabled Zod-likes to be embedded into JSON Schema via keyword extension, and where TypeBox could assume a role of validation and inference system for both JSON Schema and Standard Schema specifications (pre-1.0.28 versions have this capability). The intent was to provide assistance for frameworks having difficulties integrating both Json Schema and Zod-likes.

Unifying Json Schema with Standard Schema was a significant consideration during TBV1 development.

However, given the complexities of hosting remote libraries in JSON Schema, and since many Standard Schema implementations now support JSON Schema translation, I see little benefit in trying to pursue remote library compatibility via Standard Schema when these libraries can be made to interoperate by transforming them to JSON Schema.

const T = Type.Object({
  x: z.toJSONSchema(z.string()) // Z4 - transform | exterior
})

Support for JSON Schema translation in remote libraries was the main reason for dropping Standard Schema, along with additional concerns that the design of Standard Schema (and subsequent adoption) was rendering JSON Schema (and by extension TypeBox) incompatible with OpenAPI in various ecosystem projects (as per reference link).

Final Thoughts

TypeBox considers JSON Schema to be the only (current) viable canonical representation for runtime types, one that enables TypeScript to be encoded as a network-transmissible schema format that can be understood by any system or language with a compliant validator. If efforts had been put into establishing JSON Schema (or an extension thereof) as a common representational format shared by all libraries, there wouldn't be a need for Standard Schema at all.

Related: https://json-schema.org/draft/2020-12/json-schema-core#name-non-json-instances

The move to JSON Schema appears to be happening gradually, as most libraries are offering some form of JSON Schema translation support in light of AI / MCP tooling requirements. This raises questions about the necessity of Standard Schema, particularly when it has been demonstrated for years that both validation and TS inference can be derived entirely from JSON schematics.

Ultimately, my view is that runtime type libraries should be nothing more than compositional builders to assist with the construction of formal schematics and nothing more. Data validation should be delegated to trusted, secure, high performance systems that are vetted to take on the critical role of ensuring data integrity. This has been the TypeBox modus operandi since the very beginning.

References:

Specification: JSON Schema Specification
Ecma: JSON Schema Standardization under Ecma International.
Implementations: Valibot | Zod | ArkType.


This update is being pushed under 1.0.x stabilization revisions. Apologies to early adopters.

Fallback

The following adapter is located in example/standard/standard.ts

import StandardSchema, { type StandardSchemaV1 } from './standard/standard.ts'
import Type from 'typebox'

const T = StandardSchema(Type.Object({
  x: Type.Number(),
  y: Type.Number(),
  z: Type.Number()
}))

type T = StandardSchemaV1.InferInput<typeof T> // type T = {
                                               //   x: number,
                                               //   y: number,
                                               //   z: number
                                               // }

const R = T['~standard'].validate({            // const R: StandardSchemaV1.Result<{
  x: 1,                                        //   x: number;
  y: 2,                                        //   y: number;
  z: 3                                         //   z: number;
})                                             // }> | Promise<StandardSchemaV1.Result<{
                                               //   x: number;
                                               //   y: number;
                                               //   z: number;
                                               // }>>

@sinclairzx81 sinclairzx81 changed the title Remove Standard Schema Version 1.0.28 Oct 5, 2025
@sinclairzx81 sinclairzx81 merged commit 48f4363 into main Oct 5, 2025
6 checks passed
@sinclairzx81 sinclairzx81 deleted the remove branch October 5, 2025 21:14
sinclairzx81 added a commit that referenced this pull request Oct 5, 2025
- Remove Standard Schema
@colinhacks

colinhacks commented Nov 25, 2025

Copy link
Copy Markdown

Will/can the result of Compile still conform to the spec? This is how I expected typebox to implement spec compatibility, since (as you described) the types themselves do not encapsulate their own validation logic. It makes total sense for the

As long as the result of Compile() is spec-compliant then I'd consider TypeBox to be a fully compatible library. I'd much prefer this to exposing a special StandardSchema adapter which (in my eyes) is against the goals of the spec (that is, avoiding adapters).

@sinclairzx81

sinclairzx81 commented Nov 26, 2025

Copy link
Copy Markdown
Owner Author

@colinhacks Hello,

The only aspect of Standard Schema I was interested in exploring was a feature called "Remote Schema Embedding" which would have let Standard Schema be embedded into Json Schema schematics via ~standard keyword extension (and be accelerated via the TB compiler)

const T = Compile({
  type: 'object',
  required: ['zod', 'valibot'],
  properties: {
     zod: z.number(),
     valibot: v.number(),
  }
})

... and also possibly support for this.

const T = z.object({
  x: z.number(),
  y: z.number(),
  z: z.number()
})

// Mapped Zod Types.

const S = Type.Script({ T }, `{
  [K in keyof T]: T[K] | null
}`)                               // const S: TObject<{
                                  //   x: TUnion<[TNumber, TNull]>,
                                  //   y: TUnion<[TNumber, TNull]>,
                                  //   z: TUnion<[TNumber, TNull]>
                                  // }>

// Inference Zod Types.

const X = Type.Script({ T }, `T extends {
  x: infer X,
  y: infer Y,
  z: infer Z
} ? [X, Y, Z] : never`)           // const X: TTuple<[
                                  //   TNumber,
                                  //   TNumber,
                                  //   TNumber
                                  // ]>

Unfortunately, information regarding the design of Standard Json Schema was not particularly forth coming at the time. And without indication the specification was going to support a minimum set of features (runtime and type-level schema introspection being the main ones), I wasn't prepared to risk Standard Schema being so deeply integrated into TB in the way it was ... so I pulled support.


As long as the result of Compile() is spec-compliant then I'd consider TypeBox to be a fully compatible library. I'd much prefer this to exposing a special StandardSchema adapter which (in my eyes) is against the goals of the spec (that is, avoiding adapters).

The Compile and StandardSchema functions are both Adapters (by this definition)

const C = Compile({ type: 'string' })            //  C: Validator<...>
//    │   │         │       
//    │   │         └────────> Json Schema
//    │   │       
//    │   └──────────────────> Adapter
//    │                    
//    └──────────────────────> Validator

const S = StandardSchema({ type: 'string' })     // S: StandardSchemaV1<...>
//    │   │              │       
//    │   │              └───> Json Schema
//    │   │       
//    │   └──────────────────> Adapter
//    │                    
//    └──────────────────────> StandardSchema 

One function is more descriptive, doesn't require a "Validator" to be considered a "Schema" and separates concerns related to runtime Result and Issue mapping (as mandated by this specification). Also Effect


... is against the goals of the spec (that is, avoiding adapters).

For the purposes of system integration, we have the same goals ... no adapters

Json Schema TypeScript https://tsplay.dev/N7vM4w
Json Schema https://tsplay.dev/NdMz6m
Standard Schema Zod https://tsplay.dev/mZMe9N
Valibot https://tsplay.dev/wEKMbm
ArkType https://tsplay.dev/m0jMrw

The problem is that Standard Schema encodes Zod-like design patterns (schema / validator coupling) while presenting this design as the "Standard". This will negatively impact users of alternative software design patterns (including users of the Json Schema specification) which now need adapters to be considered "Standard" with diminished DX.

The broader concern is that Standard Schema adoption will lockout alternative software design when that doesn't need to be the case. Should Json Schema see standardization under Ecma International, developers wanting to target the specification will need adapters through Standard Schema to use it (as is the case for TB)


Adapters do provide clear explicit transformation (they are fine, fwiw)

const A = z.toJSONSchema(z.string())  // Standard Schema > Json Schema

const B = StandardSchema(A)           // Json Schema > Standard Schema      

Standard Json Schema looks like it is trying to turn this

server.post('/', {                  // 2. server compiles json schema
  body: { type: 'string' }          // 1. caller passes json schema
}, (...) => {...})

into this ...

server.post('/', {
  body: { type: 'string' }           // error: "Json Schema" is not "Standard Json Schema"
}, (...) => {...})                   //        (i.e. use Zod, Valibot, ArkType)

What should I make of this?


I am open to continued discussion, but my preference is to have TypeBox removed from the "Implementer" list as I do not provide direct support for this specification. I only provide a reference / example adapter to it (which is not published with the library)

https://github.com/sinclairzx81/typebox/tree/main/example/standard

I will take a look at the spec again next year once Json Schema has been added.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants