xsschema
extra-small, Standard Schema-based alternative to typeschema.
npm i xsschema
Why xsSchema?
- Actively maintained along with xsAI.
- Support for up to libraries in the Standard Schema scope.
- Already used by xsAI, xsMCP, FastMCP, Airi and others.
Coverage
validate
doesn't require manual support and works with any Standard Schema-compatible library.
Here is the list of libraries that toJsonSchema
is compatible with:
Implementer | Version(s) | Status |
---|---|---|
Zod (zod/v4 , zod/v4/mini ) | v3.25+ | Supported |
Zod (zod/v3 , with zod-to-json-schema ) | v3.25+ | Supported |
Valibot (with @valibot/to-json-schema ) | v1.0+ | Supported |
ArkType | v2.1+ | Supported |
Effect Schema | v3.16+ | Supported |
Sury | v10.0+ | Supported |
Usage
If you're using xsAI, this package is a dependency of some of those packages - you don't need to install it separately.
toJsonSchema
import { type } from 'arktype'
import { Schema } from 'effect'
import * as S from 'sury'
import * as v from 'valibot'
import { toJsonSchema } from 'xsschema'
import { z } from 'zod'
const arktypeSchema = type({
myString: 'string',
myUnion: 'number | boolean',
}).describe('My neat object schema')
const arktypeJsonSchema = await toJsonSchema(arktypeSchema)
const effectSchema = Schema.standardSchemaV1(
Schema.Struct({
myString: Schema.String,
myUnion: Schema.Union(Schema.Number, Schema.Boolean),
}).annotations({ description: 'My neat object schema' })
)
const effectJsonSchema = await toJsonSchema(effectSchema)
const surySchema = S.schema({
myString: S.string,
myUnion: S.union([S.number, S.boolean]),
}).with(S.meta, { description: 'My neat object schema' })
const suryJsonSchema = await toJsonSchema(surySchema)
const valibotSchema = v.pipe(
v.object({
myString: v.string(),
myUnion: v.union([v.number(), v.boolean()]),
}),
v.description('My neat object schema'),
)
const valibotJsonSchema = await toJsonSchema(valibotSchema)
const zodSchema = z.object({
myString: z.string(),
myUnion: z.union([z.number(), z.boolean()]),
}).describe('My neat object schema')
const zodJsonSchema = await toJsonSchema(zodSchema)
toJsonSchemaSync (experimental)
toJsonSchema
is async (because it has to await import
the vendor's dependencies), but we also support a synchronous version: toJsonSchemaSync
.
Before using toJsonSchemaSync
, you must call initToJsonSchemaSyncVendor
with your schema vendor.
You can register multiple schema vendors if you need to.
import { type } from 'arktype'
import { Schema } from 'effect'
import * as S from 'sury'
import * as v from 'valibot'
import { initToJsonSchemaSyncVendor, toJsonSchemaSync } from 'xsschema'
import { z } from 'zod'
const arktypeSchema = type({
myString: 'string',
myUnion: 'number | boolean',
}).describe('My neat object schema')
await initToJsonSchemaSyncVendor('arktype')
const arktypeJsonSchema = toJsonSchemaSync(arktypeSchema)
const effectSchema = Schema.standardSchemaV1(
Schema.Struct({
myString: Schema.String,
myUnion: Schema.Union(Schema.Number, Schema.Boolean),
}).annotations({ description: 'My neat object schema' })
)
await initToJsonSchemaSyncVendor('effect')
const effectJsonSchema = toJsonSchemaSync(effectSchema)
const surySchema = S.schema({
myString: S.string,
myUnion: S.union([S.number, S.boolean]),
}).with(S.meta, { description: 'My neat object schema' })
await initToJsonSchemaSyncVendor('sury')
const suryJsonSchema = toJsonSchemaSync(surySchema)
const valibotSchema = v.pipe(
v.object({
myString: v.string(),
myUnion: v.union([v.number(), v.boolean()]),
}),
v.description('My neat object schema'),
)
await initToJsonSchemaSyncVendor('valibot')
const valibotJsonSchema = toJsonSchemaSync(valibotSchema)
const zodSchema = z.object({
myString: z.string(),
myUnion: z.union([z.number(), z.boolean()]),
}).describe('My neat object schema')
await initToJsonSchemaSyncVendor('zod')
const zodJsonSchema = toJsonSchemaSync(zodSchema)
validate
import { validate } from 'xsschema'
import { type } from 'arktype'
import { Schema } from 'effect'
import * as S from 'sury'
import * as v from 'valibot'
import * as z from 'zod'
const arktypeSchema = type("string")
const effectSchema = Schema.standardSchemaV1(Schema.String)
const surySchema = S.string
const valibotSchema = v.string()
const zodSchema = z.string()
const arktypeResult = await validate(arktypeSchema, '123')
const effectResult = await validate(effectSchema, '123')
const suryResult = await validate(surySchema, '123')
const valibotResult = await validate(valibotSchema, '123')
const zodResult = await validate(zodSchema, '123')
jsonSchema
Define a JSON Schema.
import { jsonSchema } from 'xsschema'
const schema = jsonSchema({
type: 'object',
properties: {
productId: {
description: 'The unique identifier for a product',
type: 'integer'
}
}
})
strictJsonSchema
Define a JSON Schema and set additionalProperties to false
.
import { strictJsonSchema } from 'xsschema'
const schema = strictJsonSchema({
type: 'object',
properties: {
productId: {
description: 'The unique identifier for a product',
type: 'integer'
}
}
})
// false
console.log(schema.additionalProperties)
Types
Schema
Pre-bundled version of StandardSchemaV1
in @standard-schema/spec
. You can avoid installing @standard-schema/spec
to save some bulk.
JsonSchema
Pre-bundled version of JsonSchema7
in @types/json-schema
. You can avoid installing @types/json-schema
to save some bulk.
Infer
Alias for StandardSchemaV1.Infer
.
InferIn
Alias for StandardSchemaV1.InferInput
.
Errors
Missing dependencies
Some schema providers require additional packages to convert to JsonSchema.
xsschema supports a lot of vendors, so they won't and shouldn't be set as a direct dependencies, which will lead to size growth even if you don't use them.
In a nutshell:
If you use zod v3: install zod-to-json-schema
If you use valibot: install @valibot/to-json-schema
All optional peer dependencies are noted in Coverage.
Unsupported schema vendor
This means that xsschema does not yet support this vendor.
If you are interested in adding support, please make sure the library meets the following requirements (choose one of two):
- GitHub stars is greater than 100. (If the repo is not on GitHub, refer to the next entry)
- npm package has over 1000 weekly downloads.
Last updated on