Automatically generate type-safe runtime validation from your existing TypeScript interfaces. Zero configuration, zero decorators - just add JSDoc comments for validation rules and get bulletproof runtime type checking with full TypeScript support.
- π Zero-effort validation - Automatically generates JSON Schema validators from TypeScript interfaces
- π Type-safe - Full TypeScript support with type inference and type guards
- π¦ Lightweight - Minimal dependencies, can be installed as a dev dependency
- π οΈ CLI & Programmatic API - Use as a CLI tool or integrate into your build process
- π― Selective generation - Control which types to validate using file naming conventions
- π JSDoc annotations - Add validation rules (min/max length, patterns, formats) directly in your TypeScript code
- β‘ Incremental builds - File-based caching for faster subsequent builds
- π Parallel processing - Concurrent file processing for improved performance
- π Progress reporting - Visual feedback for long-running operations
- π³ Tree-shaking friendly - Generate optimized exports for smaller bundles
- π€ Lazy loading - Optional deferred validator initialization
- π¦ Minified output - Compressed JSON schemas for production
- π§ Verbose logging - Detailed debugging information when needed
- Node.js >= 12
- TypeScript >= 4.0
ajv>= 8.11.0 (peer dependency for runtime validation)
# Using yarn (recommended)
yarn add --dev ts-runtime-validation
yarn add ajv # Required peer dependency
# Using npm
npm install --save-dev ts-runtime-validation
npm install ajv # Required peer dependencyCreate files ending with .jsonschema.ts for types you want to validate:
// user.jsonschema.ts
export interface IUser {
id: string;
email: string;
name?: string;
age: number;
roles: string[];
}
export type UserRole = "admin" | "user" | "guest";You can add validation constraints using JSDoc annotations that will be converted to JSON Schema properties:
// api.jsonschema.ts
export interface IGetUserFormsPathParams {
/**
* User ID to get forms for
* @minLength 24
* @maxLength 24
* @pattern ^[a-fA-F0-9]{24}$
*/
readonly userId: string;
}
export interface IProduct {
/**
* Product name
* @minLength 1
* @maxLength 100
*/
name: string;
/**
* Product price in cents
* @minimum 0
* @maximum 1000000
* @multipleOf 1
*/
price: number;
/**
* Product tags
* @minItems 1
* @maxItems 10
* @uniqueItems true
*/
tags: string[];
/**
* Email for support
* @format email
*/
supportEmail?: string;
/**
* Product website
* @format uri
* @pattern ^https://
*/
website?: string;
}Supported JSDoc annotations include:
- Strings:
@minLength,@maxLength,@pattern,@format(email, uri, uuid, date-time, etc.) - Numbers:
@minimum,@maximum,@exclusiveMinimum,@exclusiveMaximum,@multipleOf - Arrays:
@minItems,@maxItems,@uniqueItems - Objects:
@minProperties,@maxProperties - General:
@description,@default,@examples
{ "scripts": { "generate-types": "ts-runtime-validation" } }yarn generate-typesimport { isValidSchema } from "./.ts-runtime-validation/isValidSchema";
import { IUser } from "./user.jsonschema";
const userData = await fetch("/api/user").then((r) => r.json());
if (isValidSchema(userData, "#/definitions/IUser")) {
// userData is now typed as IUser
console.log(userData.email); // TypeScript knows this is a string
} else {
console.error("Invalid user data received");
}ts-runtime-validation [options]
Core Options:
--glob <pattern> Glob pattern for schema files
(default: "*.jsonschema.{ts,tsx}")
--rootPath <rootFolder> Source directory root
(default: "./src")
--output <outputFolder> Output directory for generated files
(default: "./.ts-runtime-validation")
--tsconfigPath <path> Path to tsconfig.json
(default: "")
--generate-helpers Generate TypeScript helper files
(default: true)
--additionalProperties Allow additional properties in validation
(default: false)
Performance Options:
--cache Enable file caching for incremental builds
--no-parallel Disable parallel processing (enabled by default)
--verbose Enable detailed logging and debugging info
--progress Show progress bars and status updates
Output Optimization:
--minify Minify generated JSON schemas
--tree-shaking Generate tree-shaking friendly exports
--lazy-load Generate lazy-loaded validators
General:
-h, --help Display help informationThe tool generates optimized files in your output directory:
| File | Description | Optimizations |
|---|---|---|
validation.schema.json |
JSON Schema definitions for all your types | Minification with --minify |
SchemaDefinition.ts |
TypeScript interface mapping schema paths to types | Tree-shaking ready imports |
isValidSchema.ts |
Type guard helper with runtime validation | Lazy loading with --lazy-load |
ValidationType.ts |
Centralized type exports | Individual exports or namespace |
import { SchemaGenerator } from "ts-runtime-validation";
// Basic usage
const generator = new SchemaGenerator({
glob: "**/*.jsonschema.ts",
rootPath: "./src",
output: "./validation",
helpers: true,
additionalProperties: false,
tsconfigPath: "",
});
await generator.Generate();
// Development configuration (fast iterations)
const devGenerator = new SchemaGenerator({
glob: "**/*.jsonschema.ts",
rootPath: "./src",
output: "./.ts-runtime-validation",
helpers: true,
additionalProperties: false,
tsconfigPath: "",
// Development optimizations
cache: true, // Enable incremental builds
progress: true, // Show progress feedback
verbose: true, // Detailed logging
parallel: true, // Faster processing
});
// Production configuration (optimized output)
const prodGenerator = new SchemaGenerator({
glob: "**/*.jsonschema.ts",
rootPath: "./src",
output: "./dist/validation",
helpers: true,
additionalProperties: false,
tsconfigPath: "./tsconfig.json",
// Production optimizations
cache: true, // Faster builds
minify: true, // Smaller output files
treeShaking: true, // Bundle optimization
lazyLoad: false, // Eager loading for performance
parallel: true, // Maximum speed
});
// Large project configuration (memory efficient)
const largeProjectGenerator = new SchemaGenerator({
glob: "**/*.jsonschema.ts",
rootPath: "./src",
output: "./validation",
helpers: true,
additionalProperties: false,
tsconfigPath: "",
// Large project optimizations
cache: true, // Essential for large projects
progress: true, // Track long operations
lazyLoad: true, // Reduce initial memory usage
treeShaking: true, // Optimize bundle size
minify: true, // Reduce file size
});
// Execute generation
try {
await generator.Generate();
console.log("Schema generation completed successfully!");
} catch (error) {
console.error("Generation failed:", error.message);
}
// Utility methods
generator.clearCache(); // Clear file cache
await generator.cleanOutput(); // Remove generated files{
"scripts": {
"generate-types": "ts-runtime-validation --cache --progress",
"generate-types:watch": "nodemon --watch 'src/**/*.jsonschema.ts' --exec 'yarn generate-types'",
"generate-types:dev": "ts-runtime-validation --cache --verbose --progress",
"generate-types:prod": "ts-runtime-validation --cache --minify --tree-shaking",
"generate-types:clean": "rimraf .ts-runtime-validation-cache && yarn generate-types"
}
}# Basic usage
ts-runtime-validation
# Custom file patterns
ts-runtime-validation --glob "**/*.types.ts"
ts-runtime-validation --glob "**/*.{types,schemas}.ts"
# Development workflow (fast iterations)
ts-runtime-validation --cache --progress --verbose
# Production build (optimized output)
ts-runtime-validation --cache --minify --tree-shaking
# Large projects (performance focused)
ts-runtime-validation --cache --progress --lazy-load
# Specific directories
ts-runtime-validation --rootPath "./src/api" --output "./api-validation"
# CI/CD optimized
ts-runtime-validation --cache --minify --no-parallel
# Debug mode (maximum verbosity)
ts-runtime-validation --verbose --progress --no-parallelts-runtime-validation includes an intelligent caching system for faster incremental builds:
# Enable caching (recommended for development)
ts-runtime-validation --cacheHow it works:
- Generates MD5 hashes of source files to detect changes
- Stores cache in
.ts-runtime-validation-cache/ - Only processes files that have been modified
- Provides significant speedup for large projects
Clearing the cache:
If you encounter issues with stale generated files or need to force a full regeneration:
# Method 1: Delete cache directory
rm -rf .ts-runtime-validation-cache
# Method 2: Using programmatic API
const generator = new SchemaGenerator(options);
generator.clearCache();
# Method 3: Add a clean script to package.json
"scripts": {
"generate-types:clean": "rm -rf .ts-runtime-validation-cache && ts-runtime-validation --cache"
}Development Workflow:
# Fast iterations with caching and progress
ts-runtime-validation --cache --progress --verboseProduction Builds:
# Optimized output for deployment
ts-runtime-validation --cache --minify --tree-shakingLarge Projects:
# Memory efficient processing
ts-runtime-validation --cache --lazy-load --progressTree-shaking friendly exports:
// With --tree-shaking flag
export type IUser = _IUser; // Individual exports
export type IProduct = _IProduct;
// Default behavior
namespace ValidationType {
// Namespace exports
export type IUser = _IUser;
}Lazy-loaded validators:
// With --lazy-load flag
let validator: any = null;
const getValidator = () => {
if (!validator) {
const Ajv = require("ajv");
validator = new Ajv({ allErrors: true });
validator.compile(schema);
}
return validator;
};- No duplicate type names - Each interface/type must have a unique name across all schema files
- TypeScript-only constructs - Some advanced TypeScript features (like conditional types) may not be fully supported
- Circular references - Limited support for circular type references
We welcome contributions! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
# Clone the repository
git clone https://github.com/thegalah/ts-runtime-validation.git
cd ts-runtime-validation
# Install dependencies
yarn install
# Build the project
yarn build
# Run comprehensive test suite (103+ tests)
yarn test
# Link for local development
yarn linkts-runtime-validation uses a modern service-oriented architecture:
- FileDiscovery: File system operations and intelligent caching
- SchemaProcessor: TypeScript AST processing with parallel execution
- CodeGenerator: Optimized TypeScript file generation
- SchemaWriter: Efficient file writing with minification
- ProgressReporter: User-friendly progress tracking
See CONTRIBUTING.md for detailed information about:
- Service-oriented architecture patterns
- Error handling strategies
- Performance optimization techniques
- Testing approaches and best practices
Built with modern tools and optimized for performance:
- ts-json-schema-generator - TypeScript to JSON Schema conversion
- ajv - Runtime JSON Schema validation
- ts-morph - TypeScript AST manipulation and code generation
- fdir - Fast file system traversal
- picomatch - Efficient glob pattern matching
| Library | Approach | When to Use |
|---|---|---|
| ts-runtime-validation | Generates validators from existing TypeScript interfaces via CLI/build step | You already have TypeScript interfaces and want automatic validation without runtime dependencies or API changes |
| zod | Define schemas in code that create both types and validators | You want to define your schema once and derive TypeScript types from it, with a runtime validation library |
| io-ts | Functional programming approach with codecs for encoding/decoding | You need bidirectional transformations and prefer functional programming patterns |
| yup | Runtime schema builder with fluent API | You're working with forms/frontend validation and want a battle-tested solution with built-in error messages |
ts-runtime-validation:
- β Zero runtime API - Works with your existing TypeScript interfaces
- β Build-time generation - No runtime overhead for schema creation
- β JSDoc validation rules - Add constraints via comments
- β Intelligent caching - Fast incremental builds with change detection
- β Performance optimized - Parallel processing and bundle optimization
- β Requires build step - Must regenerate when types change
- β No runtime schema composition - Can't dynamically create schemas
zod/io-ts/yup:
- β Runtime flexibility - Create and compose schemas dynamically
- β Single source of truth - Schema and type defined together
- β No build step - Works immediately in your code
- β Runtime overhead - Schemas created at runtime
- β Duplicate type definitions - Can't reuse existing TypeScript interfaces
Choose ts-runtime-validation when you:
- Have existing TypeScript interfaces you want to validate
- Prefer build-time code generation over runtime libraries
- Want to keep validation rules close to your type definitions via JSDoc
- Need minimal runtime dependencies
- Require high performance with caching and parallel processing
- Want bundle optimization (tree-shaking, lazy loading)
- Need incremental builds for large projects
Choose alternatives when you:
- Want to define schemas at runtime dynamically
- Prefer schema-first design (define validation, derive types)
- Need complex runtime transformations or coercions
- Want extensive built-in validation methods and error messages
If your generated files seem stale or aren't reflecting recent changes:
# Clear the cache and regenerate
rm -rf .ts-runtime-validation-cache
ts-runtime-validation --cacheVersion 1.8.0+ includes fixes for deterministic output generation. If you're experiencing different file hashes between runs, ensure you're using the latest version.
For optimal performance with large codebases:
# Enable all performance optimizations
ts-runtime-validation --cache --parallel --minify --tree-shakingThe cache directory .ts-runtime-validation-cache/ can occasionally become corrupted. If you experience unexpected behavior:
- Clear the cache directory:
rm -rf .ts-runtime-validation-cache - Run generation again with cache enabled:
ts-runtime-validation --cache - Add
.ts-runtime-validation-cache/to your.gitignorefile