New:Microsoft Teams Notifications Are Now Available in Socket.Learn more
Get Started

anyschema

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

anyschema

Universal schema utilities for TypeScript. Zero dependencies. Works with Zod, Valibot, ArkType, Yup, Joi, io-ts, and more.

latest
Source
npmnpm
Version
0.4.0
Version published
Weekly downloads
3
200%
Maintainers
1
Weekly downloads
 
Created
Source

AnySchema

Universal schema utilities for TypeScript. Zero dependencies. Works with any validation library.

npm version TypeScript License: MIT

Why AnySchema?

The JavaScript ecosystem has dozens of schema validation libraries. Each has its own API, type inference, and (maybe) JSON Schema support. This fragmentation causes:

  • Lock-in — Hard to switch libraries
  • Incompatibility — Can't use schemas from different libs together
  • Duplication — Every tool rebuilds support for each library
  • Confusion — Which library should I use?

AnySchema solves this by providing a universal layer that works with ALL schema libraries:

import { validate, toJsonSchema, type InferOutput } from 'anyschema';

// Works with ANY supported schema library
validate(zodSchema, data);      // ✓
validate(valibotSchema, data);  // ✓
validate(yupSchema, data);      // ✓
validate(arktypeSchema, data);  // ✓
// ... and more

// Universal type inference
type Output = InferOutput<typeof anySchema>;

Features

  • 🎯 Zero Dependencies — No runtime deps, only peer deps for converters
  • 🔍 Auto-Detection — Automatically detects which library you're using
  • 📦 Universal API — Same API for all schema libraries
  • 🔒 Type-Safe — Full TypeScript support with type inference
  • 🚫 Compile-Time Errors — Unsupported operations fail at compile time, not runtime
  • 🌳 Tree-Shakable — Only loads what you use
  • 📋 Protocol Support — Supports Standard Schema + our own AnySchema Protocol
  • 🔮 Future-Proof — New libraries just implement the protocol

Installation

npm install anyschema

No peer dependencies required! AnySchema works with whatever schema libraries you already have installed.

Quick Start

import { validate, toJsonSchema, is, parse, type InferOutput } from 'anyschema';
import { z } from 'zod';

// Define a schema (using any supported library)
const userSchema = z.object({
  name: z.string(),
  age: z.number().min(0),
});

// Type inference
type User = InferOutput<typeof userSchema>;
// { name: string; age: number }

// Validation
const result = validate(userSchema, { name: 'John', age: 30 });
if (result.success) {
  console.log(result.data); // Typed as User
} else {
  console.log(result.issues);
}

// Type guard
if (is(userSchema, unknownData)) {
  unknownData.name; // Typed!
}

// Parse (throws on error)
const user = parse(userSchema, data);

// JSON Schema conversion
const jsonSchema = await toJsonSchema(userSchema);

Supported Libraries

LibraryValidateType InferenceJSON SchemaDetection
AnySchema Protocol~anyschema
Standard Schema❌*~standard
ZodDuck typing
ValibotDuck typing
ArkTypeDuck typing
YupDuck typing
JoiDuck typing
io-tsDuck typing
SuperstructDuck typing
TypeBoxDuck typing
Effect SchemaDuck typing

*Standard Schema doesn't define JSON Schema conversion. AnySchema adds it via duck typing fallback.

Type-Safe Operations

Operations that aren't supported by a library result in compile-time errors, not runtime errors:

import Joi from 'joi';

const joiSchema = Joi.string();

// ❌ Compile-time error! Joi doesn't support type inference
validate(joiSchema, data);
// Error: Argument of type 'StringSchema' is not assignable to 'InferCapable'

// ❌ Compile-time error! Joi doesn't support JSON Schema
toJsonSchema(joiSchema);
// Error: Argument of type 'StringSchema' is not assignable to 'JsonSchemaCapable'

// ✅ Use the untyped version if you really need it
validateAny(joiSchema, data); // Returns ValidationResult<unknown>

API Reference

Validation

validate(schema, data)

Validate data against a schema with full type inference.

function validate<T extends InferCapable>(
  schema: T,
  data: unknown
): ValidationResult<InferOutput<T>>;
const result = validate(schema, { name: 'John' });
if (result.success) {
  result.data; // Fully typed
} else {
  result.issues; // Array of { message, path? }
}

validateAsync(schema, data)

Async validation for schemas that support it.

const result = await validateAsync(asyncSchema, data);

validateAny(schema, data)

Validate without type inference (escape hatch).

const result = validateAny(anySchema, data);
// Returns ValidationResult<unknown>

Type Guards

is(schema, data)

Type guard that narrows the type of data.

function is<T extends InferCapable>(
  schema: T,
  data: unknown
): data is InferOutput<T>;
if (is(userSchema, data)) {
  data.name; // TypeScript knows data is User
}

assert(schema, data)

Assert that data matches schema, throws if not.

function assert<T extends InferCapable>(
  schema: T,
  data: unknown
): asserts data is InferOutput<T>;
assert(userSchema, data);
data.name; // TypeScript knows data is User

Parsing

parse(schema, data)

Parse data, throwing on validation errors.

function parse<T extends InferCapable>(
  schema: T,
  data: unknown
): InferOutput<T>;
try {
  const user = parse(userSchema, data);
} catch (error) {
  // ValidationError with issues
}

parseAsync(schema, data)

Async version of parse.

const user = await parseAsync(asyncSchema, data);

JSON Schema

toJsonSchema(schema)

Convert a schema to JSON Schema (async, tree-shakable).

function toJsonSchema<T extends JsonSchemaCapable>(
  schema: T
): Promise<JSONSchema>;
const jsonSchema = await toJsonSchema(zodSchema);
// { type: 'object', properties: { ... } }

toJsonSchemaSync(schema)

Sync version (uses require()).

const jsonSchema = toJsonSchemaSync(zodSchema);

Metadata

getMetadata(schema)

Extract metadata from a schema.

function getMetadata<T extends MetadataCapable>(
  schema: T
): SchemaMetadata;
const meta = getMetadata(schema);
// { title?, description?, examples?, default?, deprecated? }

Detection

detectVendor(schema)

Detect which library a schema is from.

detectVendor(zodSchema);    // 'zod'
detectVendor(yupSchema);    // 'yup'
detectVendor(customSchema); // 'anyschema' or 'standard-schema' or null

Type Guards

isZodSchema(schema);        // schema is ZodLike
isValibotSchema(schema);    // schema is ValibotLike
isArkTypeSchema(schema);    // schema is ArkTypeLike
isYupSchema(schema);        // schema is YupLike
// ... etc

Type Inference

InferOutput<T>

Infer the output type from any supported schema.

import { z } from 'zod';
import * as v from 'valibot';
import { type } from 'arktype';

const zodSchema = z.object({ name: z.string() });
type A = InferOutput<typeof zodSchema>; // { name: string }

const valibotSchema = v.object({ name: v.string() });
type B = InferOutput<typeof valibotSchema>; // { name: string }

const arktypeSchema = type({ name: 'string' });
type C = InferOutput<typeof arktypeSchema>; // { name: string }

InferInput<T>

Infer the input type (before transforms).

const schema = z.string().transform(s => s.length);
type Input = InferInput<typeof schema>;   // string
type Output = InferOutput<typeof schema>; // number

IsValidSchema<T>

Check if a type is a valid schema.

type A = IsValidSchema<z.ZodString>;  // true
type B = IsValidSchema<{ foo: string }>; // false

Capability Types

AnySchema uses capability types to enforce type safety at compile time:

// Only schemas that support JSON Schema conversion
type JsonSchemaCapable = ...;

// Only schemas that support type inference
type InferCapable = ...;

// Only schemas that support async validation
type AsyncCapable = ...;

// Only schemas that have metadata
type MetadataCapable = ...;

Functions use these as constraints:

// This function ONLY accepts JsonSchemaCapable schemas
function toJsonSchema<T extends JsonSchemaCapable>(schema: T): Promise<JSONSchema>;

// Passing a non-capable schema results in a compile-time error!

AnySchema Protocol

For library authors who want first-class AnySchema support.

Specification

interface AnySchemaV1<Output = unknown, Input = unknown> {
  // Required: Identity marker
  readonly '~anyschema': {
    readonly version: 1;
    readonly vendor: string;
  };

  // Required: Type carriers (compile-time only)
  readonly '~types': {
    readonly input: Input;
    readonly output: Output;
  };

  // Required: Validation
  readonly '~validate': (data: unknown) => ValidationResult<Output>;

  // Optional: Async validation
  readonly '~validateAsync'?: (data: unknown) => Promise<ValidationResult<Output>>;

  // Optional: JSON Schema conversion
  readonly '~toJsonSchema'?: () => JSONSchema;

  // Optional: Coercion
  readonly '~coerce'?: (data: unknown) => unknown;

  // Optional: Metadata
  readonly '~meta'?: {
    readonly title?: string;
    readonly description?: string;
    readonly examples?: readonly unknown[];
    readonly default?: Output;
    readonly deprecated?: boolean;
  };
}

Creating a Protocol-Compliant Schema

import { createSchema } from 'anyschema';

const myStringSchema = createSchema<string>({
  vendor: 'my-library',
  validate: (data) => {
    if (typeof data === 'string') {
      return { success: true, data };
    }
    return {
      success: false,
      issues: [{ message: 'Expected string' }]
    };
  },
  toJsonSchema: () => ({ type: 'string' }),
  meta: {
    title: 'String',
    description: 'A string value',
  },
});

// Now works with all AnySchema functions
validate(myStringSchema, 'hello');  // ✓
toJsonSchema(myStringSchema);       // ✓
type Output = InferOutput<typeof myStringSchema>; // string

Standard Schema Compatibility

AnySchema is a superset of Standard Schema. Any library implementing Standard Schema automatically works with AnySchema:

// If a library implements Standard Schema...
const schema = {
  '~standard': {
    version: 1,
    vendor: 'my-lib',
    validate: (data) => ({ value: data }),
  }
};

// ...it works with AnySchema!
validate(schema, data); // ✓

AnySchema extends Standard Schema with:

  • JSON Schema conversion
  • Metadata extraction
  • Coercion support
  • More type utilities

Detection Priority

AnySchema detects schemas in this order:

  • AnySchema Protocol (~anyschema) — Our protocol, highest priority
  • Standard Schema (~standard) — Community standard
  • Duck Typing — Fallback for all other libraries
function detectSchema(schema: unknown) {
  // 1. AnySchema Protocol
  if ('~anyschema' in schema) return 'anyschema';

  // 2. Standard Schema
  if ('~standard' in schema) return 'standard-schema';

  // 3. Duck typing
  if (isZodLike(schema)) return 'zod';
  if (isValibotLike(schema)) return 'valibot';
  // ... etc
}

Tree Shaking

AnySchema uses dynamic imports for JSON Schema converters:

// Only loads zod-to-json-schema when you actually use it
const jsonSchema = await toJsonSchema(zodSchema);

This means your bundle only includes the code you use.

Error Handling

ValidationResult

type ValidationResult<T> =
  | { success: true; data: T }
  | { success: false; issues: ValidationIssue[] };

interface ValidationIssue {
  message: string;
  path?: (string | number)[];
}

ValidationError

Thrown by parse() and assert():

class ValidationError extends Error {
  issues: ValidationIssue[];
}

Comparison

vs Standard Schema

FeatureStandard SchemaAnySchema
Validation
Type inference
JSON Schema
Metadata
Coercion
Duck typing fallback
Compile-time capability checks
AdoptionGrowing

vs Direct Library Usage

FeatureDirectAnySchema
Type safety
Library lock-in
Universal API
Mix libraries
JSON Schema (universal)

Contributing

Contributions are welcome! Please see CONTRIBUTING.md.

License

MIT © AnySchema Contributors

Powered by Sylphx

Built with @sylphx/doctor for project health checks and standards enforcement.

Keywords

schema

FAQs

Package last updated on 30 Nov 2025

Related posts