Skip to content

Property Validator

Runtime type validation with TypeScript inference and high performance.

Overview

Property Validator provides schema-based runtime type validation with full TypeScript type inference and elite performance. Beats Zod 2-72x in all categories, matches Valibot on primitives while dominating objects/arrays, and competes with TypeBox JIT.

Status: Production Ready (v0.10.0)

Language: TypeScript

Tests: 898 tests passing

Bundle Size: 30KB minified, 8KB gzipped

Repository: tuulbelt/property-validator

Features

Tree-Shakeable Imports (v0.9.0)

Import only what you need with named exports:

typescript
// Named exports - tree-shakeable
import { string, number, object, validate } from '@tuulbelt/property-validator';

// Fluent API - v namespace (also from main entry)
import { v, validate } from '@tuulbelt/property-validator';

Three API Tiers (v0.8.5)

Choose your speed vs. detail trade-off:

APISpeedReturnsUse Case
validate()~170 nsResult with errorsForms, APIs, debugging
check()~60 nsBoolean onlyFiltering, conditionals
compileCheck()~55 nsPre-compiled booleanHot paths, pipelines

Built-in Validators (v0.8.5)

Common validation patterns included:

typescript
// String validators
v.string().email()    // RFC 5322 email
v.string().url()      // HTTP/HTTPS URL
v.string().uuid()     // UUID v1-v5
v.string().min(3).max(100)

// Number validators
v.number().int()      // Integer only
v.number().positive() // > 0
v.number().range(0, 100)

Schema-Based Validation

Define schemas once, get both runtime validation and TypeScript types automatically.

Clear Error Messages

Validation errors include exact paths to invalid fields, expected vs actual types, and helpful context.

Zero Runtime Dependencies

Uses only Node.js built-ins. No npm install required in production.

Performance

Property Validator v0.10.0 delivers elite performance with JIT-style optimizations.

External Comparison Results (v0.10.0)

CategorypropvalZodValibotTypeBox JIT
Primitives62 ns123 ns59 ns61 ns
Simple Objects56 ns742 ns169 ns57 ns
Complex Nested58 ns4.21 µs584 ns56 ns
Unions56 ns426 ns123 ns57 ns
Arrays (100)145 ns4.85 µs1.10 µs108 ns

Summary

  • vs Zod: 2.0x - 72x faster ✅ (all categories)
  • vs Valibot: 2.2x - 10x faster on objects/arrays, ~tie on primitives
  • vs TypeBox JIT: Competitive (~tie overall, TypeBox uses new Function() JIT)

API Performance Comparison

Scenariovalidate()check()compileCheck()
Simple Object170 ns58 ns55 ns
Complex Nested190 ns60 ns58 ns
Union (3 types)90 ns66 ns56 ns
Invalid Data357 ns55 ns55 ns

Key insight: check() is 6x faster for invalid data (skips error path entirely).

Quick Start

bash
# Clone the repository
git clone https://github.com/tuulbelt/property-validator.git
cd property-validator
npm install

Basic Usage

typescript
import { object, string, number, validate } from '@tuulbelt/property-validator';

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

const result = validate(UserSchema, unknownData);
if (result.ok) {
  console.log(result.value); // TypeScript knows the exact type
} else {
  console.error(result.error.message);
}

Fast Boolean Check

typescript
import { check, object, string } from '@tuulbelt/property-validator';

const UserSchema = object({ name: string() });

// Fast pass/fail - no error details
if (check(UserSchema, data)) {
  processUser(data);
}

// Filter arrays efficiently
const validUsers = users.filter(u => check(UserSchema, u));

Pre-compiled for Hot Paths

typescript
import { compileCheck, object, number } from '@tuulbelt/property-validator';

const PointSchema = object({ x: number(), y: number() });
const isValidPoint = compileCheck(PointSchema);  // Compile once

// Use in hot loops
for (const point of points) {
  if (isValidPoint(point)) {
    render(point);
  }
}

Use Cases

  • API Response Validation: Verify external API data matches expected schemas
  • User Input Validation: Validate form data, CLI arguments, or configuration files
  • High-Throughput Pipelines: Use check() or compileCheck() for data filtering
  • Component Props: Validate props at runtime in any framework (React, Vue, etc.)

Demo

See the tool in action:

Property Validator Demo

▶ View interactive recording on asciinema.org

Try it online:Open in StackBlitz

What's New

v0.10.0 - Full Modularization + JSON Schema

  • JSON Schema ExporttoJsonSchema() converts schemas to JSON Schema Draft 7
  • Full Modularization — Validators extracted to individual modules (index.ts: 3744→149 lines)
  • record() validator — Dynamic keys with v.record(keyValidator, valueValidator)
  • discriminatedUnion() — Efficient tagged unions with O(1) discriminator lookup
  • strict() / passthrough() — Control unknown property handling on objects
  • Extended Validatorscuid(), cuid2(), ulid(), nanoid(), base64(), hex(), jwt(), port(), latitude(), longitude(), percentage()
  • Array JIT for Objects — Optimized array-of-object validation
  • 898 tests — Comprehensive test coverage

v0.9.2 - Performance-First Architecture

  • v namespace available from main entry: import { v } from '@tuulbelt/property-validator'
  • Named exports for tree-shakeable refinements: import { email, int } from '@tuulbelt/property-validator'
  • /types entry point for zero-runtime type imports
  • JIT compilation at schema definition time for sub-100ns validation
  • Documented design philosophy: speed over bundle size

v0.9.1 - Functional Refinement API

  • Tree-shakeable refinement functions: email(), int(), positive(), etc.
  • Functional composition: string(email(), minLength(5))
  • 32 refinement exports for maximum tree-shaking
  • 44 new tests, 680 total tests passing

v0.9.0 - Modularization

  • Tree-shakeable named exports for all validators
  • Separate types module: @tuulbelt/property-validator/types
  • sideEffects: false for bundler optimization

v0.8.5 - Three API Tiers

  • check() API for boolean-only validation (~3x faster)
  • compileCheck() API for pre-compiled hot paths
  • Built-in string validators (email, url, uuid, pattern, etc.)
  • Built-in number validators (int, positive, range, etc.)

v0.8.0 - JIT Bypass Pattern

  • 5.36x faster than Valibot on complex nested objects
  • 5.97x faster on arrays
  • Recursive JIT bypass for nested validators

Next Steps

Released under the MIT License.