standard-parse
v0.5.0
Published
Schema parsing via the Standard Schema spec. Works with Zod, Valibot, Arktype, and more.
Readme
standard-parse
Unified parse API for any schema that conforms to the
Standard Schema specification — works with Zod,
Valibot, Arktype, and more.
standard-parse provides a simple, consistent interface (parse,
safeParse) for validating and parsing input using any schema that implements
the Standard Schema V1 interface.
Why?
Library authors often need to accept schemas from users without knowing which validation library they're using. Instead of supporting each library individually:
// Before: supporting multiple libraries is painful
if (isZodSchema(schema)) {
return schema.parse(input)
} else if (isValibotSchema(schema)) {
return parse(schema, input)
} else if (isArktypeSchema(schema)) {
return schema(input)
}Use standard-parse to handle any Standard Schema-compliant library:
// After: one API for all
import * as s from "standard-parse"
return s.parse(schema, input)Perfect for form libraries, API frameworks, configuration parsers, or any library that needs to work with user-provided schemas.
Features
- Works with Zod, Valibot, Arktype, and more.
- Unified API:
parse(),safeParse(),is() - Lightweight abstraction layer
- Compatible with any schema that implements Standard Schema V1.
Installation
npm install standard-parseUsage
Zod v4
import * as z from "zod/v4"
import * as s from "standard-parse"
const schema = z.object({ name: z.string() })
const result = s.safeParse(schema, { name: "Alice" })
if (result.issues) {
console.error("Invalid:", result.issues)
} else {
console.log("Valid!", result.value)
}Zod v3
import { z } from "zod/v3"
import * as s from "standard-parse"
const schema = z.object({ name: z.string() })
const result = s.safeParse(schema, { name: "Alice" })
if (result.issues) {
console.error("Invalid:", result.issues)
} else {
console.log("Valid!", result.value)
}Valibot
import * as v from "valibot"
import * as s from "standard-parse"
const schema = v.object({ name: v.string() })
const value = s.parse(schema, { name: "Alice" }) // throws on failureArktype
import { type } from "arktype"
import * as s from "standard-parse"
const schema = type({ name: "string" })
const value = s.parse(schema, { name: "Alice" })API
parse<TSchema>(schema: TSchema, input: unknown): StandardSchemaV1.InferOutput<TSchema>
Validates and returns the parsed value, or throws ValidationError on failure.
const output = s.parse(schema, input)safeParse<TSchema>(schema: TSchema, input: unknown): StandardSchemaV1.Result<StandardSchemaV1.InferOutput<TSchema>>
Returns an object with either value or issues:
const result = s.safeParse(schema, input)
if (result.issues) {
// handle errors
} else {
// result.value is typed
}is<TSchema>(schema: TSchema, input): input is StandardSchemaV1.InferOutput<TSchema>
Validates that a input is the schema, with additional type guard.
if (s.is(schema, input)) {
// input matches schema
}Types
import type { StandardSchemaV1 } from "standard-parse"
// StandardSchemaV1<TInput, TOutput>
// StandardSchemaV1.InferInput<TSchema>
// StandardSchemaV1.InferOutput<TSchema>
// StandardSchemaV1.Result<TOutput>
// StandardSchemaV1.IssueRe-exported from @standard-schema/spec.
Test Matchers
This library also includes some test matchers to make testing schemas easier in test files.
Vitest
Create a setup file that imports the matchers:
// vitest.setup.ts
import "standard-parse/test-matchers/vitest"Register it in your Vitest config:
// vitest.config.ts
import { defineConfig } from "vitest/config"
export default defineConfig({
test: {
setupFiles: ["./vitest.setup.ts"]
}
})Note: the import must live in a
.tsfile that TypeScript compiles (covered by yourtsconfig.json'sinclude). Passing the package path as a string directly tosetupFiles(e.g.setupFiles: ["standard-parse/test-matchers/vitest"]) registers the matcher at runtime but does not propagate thetoMatchSchematype augmentation to your tests. Alternatively, you can add the import to a single*.tsor*.d.tsfile anywhere in your project to make the types globally available.
Then use the toMatchSchema matcher in your tests:
import { expect, test } from "vitest"
import * as z from "zod"
const schema = z.object({ name: z.string() })
test("valid input matches schema", () => {
expect({ name: "Alice" }).toMatchSchema(schema)
})
test("invalid input does not match schema", () => {
expect({ name: 123 }).not.toMatchSchema(schema)
})
test("with additional checks", () => {
expect({ name: "Alice" }).toMatchSchema(schema, (parsed) => {
expect(parsed.name).toBe("Alice")
})
})ValidationError
parse will throw a ValidationError on failure:
import * as s from "standard-parse"
try {
s.parse(schema, badInput)
} catch (err) {
if (err instanceof s.ValidationError) {
console.error(err.issues)
}
}License (MIT)
Copyright (c) 2025 Catena Labs, Inc. See
LICENSE.
