npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

lite-schema-check

v2.1.0

Published

A tiny, zero-dependency TypeScript validation library. Competitive alternative to Zod with clearer API, solving real pain points like circular validation, codecs, and mixed async/sync validation.

Readme

lite-schema-check 🔥

Zero-dependency TypeScript validation library. A competitive alternative to Zod.

npm version License: MIT Tests TypeScript

What's New in v2.1 🔥

We implemented the TOP REQUESTED features from Zod's issue tracker:

New in v2.1 (Just Added!)

  • FormData validation (60+ votes) - Zod doesn't have it!
  • Partial validation - Return valid data even with errors
  • JSON Schema export - Better than zod-to-json-schema
  • Schema metadata extraction - Auto-generate forms
  • XOR (exclusive OR) - Cleaner than Zod's approach
  • File validation - Size & MIME type checking
  • Schema descriptions - Rich metadata support

From v2.0 (Already Have It!)

That's 11 features Zod doesn't have!

Quick Comparison

| Feature | Zod | lite-schema-check v2.1 | |---------|-----|----------------------| | Basic validation | ✅ | ✅ | | Nested objects | ✅ | ✅ | | Optional/nullable | ⚠️ (confusing) | ✅ Clearer | | FormData validation | ❌ | ✅ We have it 🔥 | | Partial validation | ❌ | ✅ We have it 🔥 | | JSON Schema export | ⚠️ (external) | ✅ Built-in 🔥 | | Schema metadata | ⚠️ (hard) | ✅ Easy 🔥 | | XOR support | ⚠️ (clunky) | ✅ Clean 🔥 | | Circular validation | ❌ | ✅ We have it | | Mixed async/sync | ❌ | ✅ We have it | | Reversible transforms | ❌ | ✅ We have it | | Bundle size | ~2KB | ~3KB minified | | Battle-tested | ✅ Years | ⚠️ Growing |

Installation

npm install lite-schema-check

Quick Start

🔥 FormData Validation (NEW!)

import { validateFormData, object, string, number, file } from 'lite-schema-check/v2';

const schema = object({
  name: string.min(3),
  age: number.positive(),
  avatar: file({ maxSize: 5_000_000, mimeTypes: ['image/png', 'image/jpeg'] })
});

// In Remix/Next.js server action:
export async function action({ request }) {
  const formData = await request.formData();
  const result = validateFormData(formData, schema);
  
  if (result.success) {
    // Automatic type conversion! age is number, not string
    await createUser(result.data);
  }
}

🔄 Partial Validation (NEW!)

import { validatePartial, object, string, number } from 'lite-schema-check/v2';

const schema = object({
  name: string.min(3),
  email: string.email(),
  age: number.positive()
});

const data = {
  name: 'John',        // ✅ Valid
  email: 'not-email',  // ❌ Invalid
  age: 30              // ✅ Valid
};

const result = validatePartial(data, schema);

// Save what's valid, show errors for what's not
await saveDraft(result.validData);  // { name: 'John', age: 30 }
showErrors(result.invalidFields);   // { email: {...} }

📄 JSON Schema Export (NEW!)

import { toJSONSchema, describe, optional } from 'lite-schema-check/v2';

const schema = object({
  name: describe(string.min(3), 'User full name'),
  age: optional(number.positive())
});

const jsonSchema = toJSONSchema(schema);
// {
//   type: 'object',
//   properties: {...},
//   required: ['name']  // ✅ 'age' correctly NOT required!
// }

Basic Validation

import { validate, object, optional, array, union, literal } from 'lite-schema-check/v2';

// Define a schema with all the features
const userSchema = object({
  name: 'string',
  age: 'number',
  email: optional('string'),        // Can be missing
  tags: array('string', { min: 1, max: 10 }),
  role: union(
    literal('admin'),
    literal('user'),
    literal('guest')
  ),
  profile: object({
    bio: 'string',
    website: optional('string')
  })
});

// Validate data
const result = validate(userData, userSchema);

if (result.success) {
  console.log('Valid!', result.data);
} else {
  console.log('Errors:', result.errors);
  // Detailed error paths: ['profile', 'bio']
}

V1 API (Still works)

import { validate } from 'lite-schema-check';

const schema = { name: 'string', age: 'number' };
const result = validate({ name: 'Alice', age: 30 }, schema);
// { isValid: true, errors: [] }

Why Choose Us Over Zod?

1. 🔥 FormData Validation (60+ Votes!)

Problem: Zod has NO FormData support. Every Remix/Next.js dev needs this.

Our Solution:

import { validateFormData, object, string, number, file } from 'lite-schema-check/v2';

const schema = object({
  name: string.min(3),
  age: number.positive(),
  avatar: file({ maxSize: 5_000_000, mimeTypes: ['image/png'] })
});

// Automatic type conversion: strings → numbers, File validation
const result = validateFormData(formData, schema);

Status: ✅ We have it | ❌ Zod doesn't


2. 🔥 Partial Validation

Problem: Zod returns nothing if ANY field fails. Can't save partial data.

Our Solution:

import { validatePartial } from 'lite-schema-check/v2';

const result = validatePartial(data, schema);

// Returns:
// {
//   validData: { name: 'John', age: 30 },    // Save these!
//   invalidFields: { email: {...} }          // Show errors
// }

await saveDraft(result.validData);  // Save what works

Use Cases: Auto-save forms, progressive validation, data migration

Status: ✅ We have it | ❌ Zod doesn't


3. 🔥 JSON Schema Export (Better than zod-to-json-schema)

Problem: Zod needs external package with bugs (optional fields marked required)

Our Solution:

import { toJSONSchema, toOpenAPISchema, describe } from 'lite-schema-check/v2';

const schema = object({
  name: describe(string.min(3), 'User full name'),
  age: optional(number.positive())
});

const jsonSchema = toJSONSchema(schema);
// ✅ Optional fields correctly NOT in required array
// ✅ Descriptions preserved
// ✅ OpenAPI 3.0 compatible

Status: ✅ Built-in | ⚠️ Zod needs external package


4. ✅ Circular/Recursive Validation (Zod Issue #5346)

Problem: Zod users struggle with tree structures, categories, comment threads.

Our Solution:

import { object, array, lazy } from 'lite-schema-check/v2';

const categorySchema = object({
  name: 'string',
  children: array(lazy(() => categorySchema))
});

// Validates infinitely nested categories!

Status: ✅ We have it | ❌ Zod doesn't (issue open since Oct 16, 2025)


2. ✅ Clearer Optional/Nullable API (Zod Issue #5348)

Problem: Zod's .required() on .optional() confuses users.

Our Solution:

import { object, optional, nullable, nullish } from 'lite-schema-check/v2';

const schema = object({
  email: optional('string'),   // Can be missing entirely
  phone: nullable('string'),   // Can be null (must be present)
  bio: nullish('string')       // Can be null OR undefined
});

Status: ✅ Clearer than Zod's API


3. ✅ Mixed Sync/Async Validation (Zod Issue #5379)

Problem: Zod is all-sync or all-async, no mixing.

Our Solution:

import { object, async } from 'lite-schema-check/v2';
import { string } from 'lite-schema-check/presets';

const schema = object({
  username: async('string', async (val) => {
    // Check database
    const exists = await checkUsernameExists(val);
    if (exists) throw new Error('Username taken');
  }),
  email: string.email()  // Sync validation
});

// Validates efficiently

Status: ✅ We support selective async | ❌ Zod doesn't


4. ✅ Reversible Transforms (Codecs) (Zod Issues #5374, #5377)

Problem: Zod transforms are one-way. Users want to serialize back.

Our Solution:

import { codec } from 'lite-schema-check/v2';

const dateCodec = codec(
  'string',
  (str) => new Date(str),       // Parse (decode)
  (date) => date.toISOString()  // Serialize (encode)
);

// Can parse API responses AND serialize back!

Status: ✅ Bidirectional | ❌ Zod is one-way only


Feature Showcase

Arrays with Constraints

import { object, array } from 'lite-schema-check/v2';

const schema = object({
  tags: array('string', { min: 1, max: 5 })
});

validate({ tags: ['js', 'ts'] });  // ✅ Valid
validate({ tags: [] });             // ❌ Too few
validate({ tags: ['a','b','c','d','e','f'] });  // ❌ Too many

Nested Objects

const orderSchema = object({
  customer: object({
    name: 'string',
    address: object({
      street: 'string',
      city: 'string',
      zip: 'number'
    })
  }),
  items: array(object({
    product: 'string',
    quantity: 'number'
  }))
});

// Validates deeply nested structures

Unions & Literals (Enums)

const taskSchema = object({
  status: union(
    literal('todo'),
    literal('in_progress'),
    literal('done')
  ),
  priority: union(literal(1), literal(2), literal(3))
});

// Type-safe enum-like validation

String Refinements

import { string } from 'lite-schema-check/presets';

const schema = object({
  email: string.email(),
  url: string.url(),
  uuid: string.uuid(),
  password: string.min(8),
  username: string.regex(/^[a-z0-9_]+$/)
});

Number Refinements

import { number } from 'lite-schema-check/presets';

const schema = object({
  age: number.positive(),
  rating: number.int(),
  price: number.min(0),
  discount: number.max(100)
});

API Reference

Core Functions

validate(input: unknown, schema: Schema): ValidationResult

Validates data against a schema.

assertValid(input: unknown, schema: Schema): asserts input

Throws if validation fails.

createValidator(schema: Schema): (input: unknown) => ValidationResult

Creates a reusable validator.

Schema Builders

  • object(shape) - Define object schema
  • optional(schema) - Mark field as optional
  • nullable(schema) - Mark field as nullable
  • nullish(schema) - Mark field as nullable OR optional
  • array(items, constraints?) - Define array with optional min/max
  • union(...options) - Multiple type options
  • literal(value) - Exact value match

Advanced Features

  • lazy(factory) - Circular/recursive schemas
  • async(schema, validator) - Async validation
  • codec(schema, decode, encode) - Reversible transforms
  • refine(schema, refiner) - Custom validation
  • transform(schema, transformer) - Data transformation

TypeScript Support

Full TypeScript support with type inference:

import { validate, object, ValidationResult } from 'lite-schema-check/v2';

const schema = object({
  name: 'string',
  age: 'number'
});

const result: ValidationResult = validate(data, schema);
if (result.success) {
  // result.data is typed!
}

When to Use lite-schema-check

✅ Use Us When:

  • 🔥 You're using Remix / Next.js - FormData validation built-in
  • 🔥 You need auto-save forms - Partial validation
  • 🔥 You need API docs - JSON Schema / OpenAPI export
  • 🔥 You're building forms - Schema metadata extraction
  • You need circular/recursive validation
  • You want clearer optional/nullable API
  • You need reversible transforms (codecs)
  • You need mixed sync/async validation
  • Bundle size matters (edge functions)
  • You prefer simpler, more predictable API

⚠️ Use Zod When:

  • You need battle-tested production stability
  • You need the richest ecosystem
  • You need advanced TypeScript type inference
  • You're already using it (migration cost)
  • You don't need the features we have

Migration from Zod

Most Zod schemas translate directly:

// Zod
z.object({
  name: z.string(),
  age: z.number(),
  email: z.string().optional()
})

// lite-schema-check
object({
  name: 'string',
  age: 'number',
  email: optional('string')
})

Most schemas migrate directly with minimal changes.

Documentation

Examples

Check the /examples folder:

  • 🔥 formdata-validation.ts - NEW! 5 FormData examples (Remix/Next.js)
  • 🔥 partial-validation.ts - NEW! 5 partial validation examples (auto-save)
  • 🔥 json-schema-metadata.ts - NEW! 6 JSON Schema examples (OpenAPI)
  • v2-vs-zod.ts - Feature comparison
  • zod-pain-points.ts - Solutions to Zod issues

Roadmap

✅ Completed (v2.1)

  • [x] Basic validation
  • [x] Optional/nullable fields
  • [x] Nested objects
  • [x] Arrays with constraints
  • [x] Unions & literals
  • [x] String/number refinements
  • [x] Circular validation (lazy)
  • [x] Async validation
  • [x] Codecs (reversible transforms)
  • [x] 🔥 FormData validation
  • [x] 🔥 Partial validation
  • [x] 🔥 JSON Schema export
  • [x] 🔥 Schema metadata
  • [x] 🔥 XOR support
  • [x] 🔥 File validation
  • [x] 🔥 Schema descriptions

📋 Coming Soon

  • [ ] Schema composition (extend, merge, pick, omit)
  • [ ] Discriminated unions
  • [ ] Better error messages
  • [ ] Performance optimization
  • [ ] Framework integrations (Remix, Next.js plugins)

Contributing

Contributions welcome! We're actively building features Zod users are asking for.

How to contribute:

  1. Watch Zod's issues
  2. Implement requested features
  3. Submit PR with tests
  4. Help us compete!

License

MIT

Acknowledgments

  • Zod - Inspiration and competition
  • ArkType - Performance ideas
  • io-ts - Type safety concepts

Made with ❤️ by developers frustrated with existing validation libraries.

Give us a try! We're actively solving problems Zod users are asking for.