Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

A standard interface for TypeScript schema validation libraries

License

NotificationsYou must be signed in to change notification settings

standard-schema/standard-schema

Repository files navigation

Standard Schema fire logo
Standard Schema

A common interface for TypeScript validation libraries
standardschema.dev


Standard Schema is a common interface designed to be implemented by JavaScript and TypeScript schema libraries.

The goal is to make it easier for ecosystem tools to accept user-defined type validators, without needing to write custom logic or adapters for each supported library. And since Standard Schema is a specification, they can do so with no additional runtime dependencies. Integrate once, validate anywhere.

Who designed it?

The spec was designed by the creators of Zod, Valibot, and ArkType. Recent versions of these libraries already implement the spec (see thefull list of compatible libraries below).

The interface

The specification consists of a single TypeScript interfaceStandardSchemaV1 to be implemented by any schema library wishing to be spec-compliant.

This interface can be found below in its entirety. Libraries wishing to implement the spec can copy/paste the code block below into their codebase. It's also available at@standard-schema/spec onnpm andJSR. There will be zero changes without a major version bump.

/** The Standard Schema interface. */exportinterfaceStandardSchemaV1<Input=unknown,Output=Input>{/** The Standard Schema properties. */readonly'~standard':StandardSchemaV1.Props<Input,Output>;}exportdeclarenamespaceStandardSchemaV1{/** The Standard Schema properties interface. */exportinterfaceProps<Input=unknown,Output=Input>{/** The version number of the standard. */readonlyversion:1;/** The vendor name of the schema library. */readonlyvendor:string;/** Validates unknown input values. */readonlyvalidate:(value:unknown)=>Result<Output>|Promise<Result<Output>>;/** Inferred types associated with the schema. */readonlytypes?:Types<Input,Output>|undefined;}/** The result interface of the validate function. */exporttypeResult<Output>=SuccessResult<Output>|FailureResult;/** The result interface if validation succeeds. */exportinterfaceSuccessResult<Output>{/** The typed output value. */readonlyvalue:Output;/** The non-existent issues. */readonlyissues?:undefined;}/** The result interface if validation fails. */exportinterfaceFailureResult{/** The issues of failed validation. */readonlyissues:ReadonlyArray<Issue>;}/** The issue interface of the failure output. */exportinterfaceIssue{/** The error message of the issue. */readonlymessage:string;/** The path of the issue, if any. */readonlypath?:ReadonlyArray<PropertyKey|PathSegment>|undefined;}/** The path segment interface of the issue. */exportinterfacePathSegment{/** The key representing a path segment. */readonlykey:PropertyKey;}/** The Standard Schema types interface. */exportinterfaceTypes<Input=unknown,Output=Input>{/** The input type of the schema. */readonlyinput:Input;/** The output type of the schema. */readonlyoutput:Output;}/** Infers the input type of a Standard Schema. */exporttypeInferInput<SchemaextendsStandardSchemaV1>=NonNullable<Schema['~standard']['types']>['input'];/** Infers the output type of a Standard Schema. */exporttypeInferOutput<SchemaextendsStandardSchemaV1>=NonNullable<Schema['~standard']['types']>['output'];}

Design goals

The specification meets a few primary design objectives:

  • Support runtime validation. Given a Standard Schema compatible validator, you should be able to validate data with it (duh). Any validation errors should be presented in a standardized format.
  • Support static type inference. For TypeScript libraries that do type inference, the specification provides a standard way for them to "advertise" their inferred type, so it can be extracted and used by external tools.
  • Minimal. It should be easy for libraries to implement this spec in a few lines of code that call their existing functions/methods.
  • Avoid API conflicts. The entire spec is tucked inside a single object property called~standard, which avoids potential naming conflicts with the API surface of existing libraries.
  • Do no harm to DX. The~standard property is tilde-prefixed tode-prioritize it in autocompletion. By contrast, an underscore-prefixed property would show up before properties/methods with alphanumeric names.

What schema libraries implement the spec?

These are the libraries that have already implemented the Standard Schema interface. (If you maintain a library that implements the spec,create a PR to add yourself!)

ImplementerVersion(s)Link
Zod3.24.0+PR
Valibotv1.0+PR
ArkTypev2.0+PR
Effect Schemav3.13.0+PR
Arri Schemav0.71.0+PR
TypeMapv0.8.0+PR
Formgatorv0.1.0+PR
decodersv2.6.0+PR
Suryv9.2.0+PR
Skunkteam Typesv9.0.0+PR
DreamIt GraphQL-Std-Schemav0.1.0+Commit
ts.data.jsonv2.3.0+PR
quartetv11.0.3+PR
unhoaxv0.7.0+Commit
protovalidate-esv0.5.0+PR
remultv3.1.1+PR
stnlv1.1.9+Commit
yupv1.7.0+PR
joiv18.0.0+PR
typiav9.2.0+PR
reglev1.9.0+PR

What tools / frameworks accept spec-compliant schemas?

The following tools accept user-defined schemas conforming to the Standard Schema spec. (If you maintain a tool that supports Standard Schemas,create a PR to add yourself!)

IntegratorDescriptionLink
tRPCMove fast and break nothing. End-to-end typesafe APIs made easyPR
TanStack FormHeadless, performant, and type-safe form state management for TS/JS, React, Vue, Angular, Solid, and LitPR
TanStack RouterA fully type-safe React router with built-in data fetching, stale-while revalidate caching and first-class search-param APIsPR
Hono MiddlewareFast, lightweight server, built on Web StandardsPR
Qwik 🚧Instant-loading web apps, without effortPR
UploadThingFile uploads for modern web devsDocs
T3 EnvFramework agnostic validation for type-safe environment variablesPR
OpenAuthUniversal, standards-based auth providerDocs
renounThe Documentation Toolkit for ReactDocs
FormwerkA Vue.js Framework for building high-quality, accessible, delightful forms.PR
GQLoomWeave GraphQL schema and resolvers using Standard SchemaPR
Nuxt UIA UI Library for modern web apps, powered by Vue & Tailwind CSSPR
oRPCTypesafe APIs made simple 🪄PR
RegleType-safe model-based form validation library for Vue.jsPR
upfetchTiny & composable fetch configuration tool with sensible defaults and built-in schema validationPR
rest-clientUltra-lightweight and easy-to-use http(s) client for node.js supporting JSON and streams with no external dependenciesDocs
make-serviceA set of utilities to improve the DX of nativefetch to better interact with external APIs.PR
call-apiA lightweight fetching library packed with essential features - retries, interceptors, request deduplication and much more, all while still retaining a similar API surface with regular Fetch.PR
cachifiedUse everything as a cache with type-safety (by Standard Schema), stale-while-revalidate, parallel-fetch deduplication, ...Docs
React Hook FormReact Hooks for form state management and validation (Web + React Native).PR
MageBuild web applications with Deno and PreactDocs
Better-fetchAdvanced fetch library for typescript, supports zod schema validations, pre-defined routes, hooks, plugins and more. Works on the browser, node (version 18+), workers, deno and bun.Docs
server-actA simple React server action builder that provides input validation.PR
xinkA filesystem API router, inspired by SvelteKitDocs
xsAIextra-small AI SDK.Docs
xsSchemaextra-small, Standard Schema-based alternative to typeschema.Docs
xsMCPextra-small MCP SDK.Docs
DreamIT GraphQL-ServerGraphQL server written in NodeJS/Typescript.PR
Astro Typesafe RoutesAn Astro integration for typesafe URL generation and routing.PR
MuppetBuild MCPs (Model Context Protocol) on top of honoRepo
ts-icsParse and generate iCalendar with TypescriptPR
kvdexA high-level abstraction layer for Deno KV. Works in Deno, Bun, Node.js and the browser 🦕🗝️PR
FastMCPA TypeScript framework for building MCP servers capable of handling client sessions.PR
RVFEasy and powerful form state management and validation for React.PR
SchemQlA lightweight TypeScript library that enhances your SQL workflow by combining raw SQL with targeted type safety and schema validationRepo
data-double-dashType-safe component framework for multi-page applications.Docs
SlonikA Node.js PostgreSQL client with runtime and build time type safety, and composable SQL.PR
Nuxt Safe Runtime ConfigValidate Nuxt runtime config at build time using Zod, Valibot, ArkType, or any Standard Schema compatible libraryDocs
Content CollectionsA library for converting content into type-safe data collections.PR
safewayA type-safe serialisation and validation wrapper for string storage APIs likelocalStorage andsessionStorage.Docs
True MythSafe, idiomatic null, error, and async code handling in TypeScript, withMaybe,Result, andTask types that are really nice.Guide
@sugardarius/anzenA flexible, framework validation agnostic, type-safe factory for creating Next.JS App Router route handlers.Docs
ConformalA framework-agnostic library for strongly typed FormData parsing.Repo
next-safe-actionType safe and validated Server Actions in your Next.js project.PR
Event TrackerA library for event tracking in React applications collections.Docs
zod-jsonrpcType-safe JSON-RPC 2.0 clients and servers.Docs
xignalsignals state management for realRepo
svelte-jsonschema-formSvelte 5 library for creating forms based on JSON schema.Docs
RTK QueryA powerful data fetching and caching tool, included with Redux Toolkit.Docs
InngestEvent-driven durable workflow engine that runs on any cloud.Docs

How can my schema library implement the spec?

Schemas libraries that want to support Standard Schema must implement theStandardSchemaV1 interface. Start by copying the specification file above into your library. It consists of types only.

Then implement the spec by adding the~standard property to your validator objects/instances. We recommend usingextends /implements to ensure static agreement with the interface. It doesn't matter whether your schema library returns plain objects, functions, or class instances. The only thing that matters is that the~standard property is defined somehow.

Here's a simple worked example of a string validator that implements the spec.

importtype{StandardSchemaV1}from'@standard-schema/spec';// Step 1: Define the schema interfaceinterfaceStringSchemaextendsStandardSchemaV1<string>{type:'string';message:string;}// Step 2: Implement the schema interfacefunctionstring(message:string='Invalid type'):StringSchema{return{type:'string',    message,'~standard':{version:1,vendor:'valizod',validate(value){returntypeofvalue==='string' ?{value} :{issues:[{message}]};},},};}

We recommend defining the~standard.validate() function in terms of your library's existing validation functions/methods. Ideally implementing the spec only requires a handful of lines of code.

Avoid returningPromise from~standard.validate() unless absolutely necessary. Some third-party libraries may not support async validation.

How do I accept Standard Schemas in my library?

Third-party libraries and frameworks can leverage the Standard Schema spec to accept user-defined schemas in a type-safe way.

To get started, copy and paste the specification file into your project. Alternatively (if you are okay with the extra dependency), you can install the@standard-schema/spec package fromnpm orJSR as a dependency.It is not recommended to install as a dev dependency, see theassociated FAQ for details.

npm install @standard-schema/spec# npmyarn add @standard-schema/spec# yarnpnpm add @standard-schema/spec# pnpmbun add @standard-schema/spec# bundeno add jsr:@standard-schema/spec# deno

Here's is an simple example of a generic function that accepts an arbitrary spec-compliant validator and uses it to parse some data.

importtype{StandardSchemaV1}from'@standard-schema/spec';exportasyncfunctionstandardValidate<TextendsStandardSchemaV1>(schema:T,input:StandardSchemaV1.InferInput<T>):Promise<StandardSchemaV1.InferOutput<T>>{letresult=schema['~standard'].validate(input);if(resultinstanceofPromise)result=awaitresult;// if the `issues` field exists, the validation failedif(result.issues){thrownewError(JSON.stringify(result.issues,null,2));}returnresult.value;}

This concise function can accept inputs from any spec-compliant schema library.

import*aszfrom'zod';import*asvfrom'valibot';import{type}from'arktype';constzodResult=awaitstandardValidate(z.string(),'hello');constvalibotResult=awaitstandardValidate(v.string(),'hello');constarktypeResult=awaitstandardValidate(type('string'),'hello');

FAQ

These are the most frequently asked questions about Standard Schema. If your question is not listed, feel free to create an issue.

Do I need to add@standard-schema/spec as a dependency?

No. The@standard-schema/spec package is completely optional. You can just copy and paste the types into your project. We guarantee no breaking changes without a major version bump.

If you don't mind additional dependencies, you can add@standard-schema/spec as a dependency and consume it withimport type. The@standard-schema/spec package contains no runtime code and only exports types.

Can I add it as a dev dependency?

Despite being types-only, you shouldnot install@standard-schema/spec as a dev dependency. By accepting Standard Schemas as part of your public API, the Standard Schema interface becomes a part of your library's public API. As such, itmust be available whenever/wherever your library gets installed, even in production installs. For this to happen, it must be installed as a regular dependency.

Why did you prefix the~standard property with~?

The goal of prefixing the key with~ is to both avoid conflicts with existing API surfaces and to de-prioritize these keys in auto-complete. The~ character is one of the few ASCII characters that occurs afterA-Za-z0-9 lexicographically, so VS Code puts these suggestions at the bottom of the list.

Screenshot showing the de-prioritization of the ~ prefix keys in VS Code.

Why not use a symbol key?

In TypeScript, using a plainSymbol inline as a key always collapses to a simplesymbol type. This would cause conflicts with other schema properties that use symbols.

constobject={[Symbol.for('~output')]:'some data',};// { [k: symbol]: string }

Unique symbols can also be declared in a "nominal" way that won't collapse. In this case the symbol key is sorted alphabetically in autocomplete according to the symbol's variable name.

Screenshot showing the prioritization of external symbols in VS Code

Thus, these symbol keys don't get sorted to the bottom of the autocomplete list, unlike tilde-prefixed string keys.

How to only allow synchronous validation?

The~validate function might return a synchronous valueor aPromise. If you only accept synchronous validation, you can simply throw an error if the returned value is an instance ofPromise. Libraries are encouraged to preferentially use synchronous validation whenever possible.

importtype{StandardSchemaV1}from'@standard-schema/spec';functionvalidateInput(schema:StandardSchemaV1,data:unknown){constresult=schema['~standard'].validate(data);if(resultinstanceofPromise){thrownewTypeError('Schema validation must be synchronous');}// ...}

[8]ページ先頭

©2009-2025 Movatter.jp