v1.1.0 - Now with Async Validation

Katax Core

Lightweight and extensible schema validation library for TypeScript/JavaScript

8+
Schema Types
100%
Type Safe
Async
Validation
MIT
License

Features

Type-Safe Validation

Full TypeScript support with complete type inference and safety.

Async Validation

Validate against databases, APIs, and external services seamlessly.

Comprehensive Schemas

String, Number, Object, Array, Date, Email, Base64, File and more.

Transform Support

Validate and transform data in one step with chaining API.

Multiple Error Reporting

Get all validation errors at once for better UX.

Zero Dependencies

Lightweight with only date-fns for date operations.

Installation

Install Katax Core via npm, yarn, or pnpm:

npm install katax-core

Quick Examples

01. Basic Validation

TypeScript
import { k } from 'katax-core';

const userSchema = k.object({
  name: k.string().minLength(2),
  email: k.string().email(),
  age: k.number().min(18).max(100),
  tags: k.array(k.string()).optional()
});

const result = userSchema.safeParse({
  name: 'John Doe',
  email: 'john@example.com',
  age: 25,
  tags: ['developer', 'typescript']
});

if (result.success) {
  console.log('Valid data:', result.data);
} else {
  console.log('Errors:', result.issues);
}

02. Async Validation

TypeScript - Database Validation
import { k } from 'katax-core';

// Async validator to check if email already exists
const emailUniqueValidator = async (email, path) => {
  const exists = await db.users.findOne({ email });
  if (exists) {
    return [{ path, message: 'Email already registered' }];
  }
  return [];
};

const registrationSchema = k.object({
  email: k.email().asyncRefine(emailUniqueValidator),
  password: k.string()
    .minLength(8)
    .regex(/[A-Z]/, 'Must contain uppercase')
    .regex(/[0-9]/, 'Must contain number')
});

// Use async validation
const result = await registrationSchema.safeParseAsync({
  email: 'user@example.com',
  password: 'SecurePass123'
});

if (result.success) {
  console.log('Valid data:', result.data);
}

03. Type Inference

TypeScript - Full Type Safety
import { k, kataxInfer } from 'katax-core';

const createProjectSchema = k.object({
  title: k.string().minLength(3),
  description: k.string().optional(),
  tags: k.array(k.string()),
  isPublic: k.boolean().default(true)
});

// Automatically infer TypeScript type
export type CreateProjectData = kataxInfer<typeof createProjectSchema>;
// Type: { title: string; description?: string; tags: string[]; isPublic: boolean }

function createProject(data: CreateProjectData) {
  // Full type safety and autocomplete
  console.log(data.title); // ✓ string
  console.log(data.tags);  // ✓ string[]
}

04. Complex Nested Schema

TypeScript - Nested Objects & Arrays
import { k } from 'katax-core';

const blogSchema = k.object({
  title: k.string().minLength(5).maxLength(100),
  slug: k.string().regex(/^[a-z0-9-]+$/),
  author: k.object({
    name: k.string(),
    email: k.email(),
    bio: k.string().optional()
  }),
  tags: k.array(k.string()).unique().minLength(1),
  publishedAt: k.date().isPast(),
  metadata: k.object({
    views: k.number().min(0).default(0),
    likes: k.number().min(0).default(0)
  }).optional()
});

const result = blogSchema.safeParse({
  title: 'Introduction to Katax Core',
  slug: 'intro-to-katax',
  author: {
    name: 'Vinicio Esparza',
    email: 'vinicio@example.com'
  },
  tags: ['typescript', 'validation'],
  publishedAt: new Date('2024-01-01')
});

Available Schemas

String Schema

k.string()
  .minLength(3)
  .maxLength(50)
  .email()
  .url()
  .regex(/^[a-zA-Z]+$/)

Number Schema

k.number()
  .min(0)
  .max(100)
  .positive()
  .integer()

Date Schema

k.date()
  .min('2024-01-01')
  .max('2024-12-31')
  .isFuture()
  .isPast()

Email Schema

k.email()
  .domain('company.com')
  .corporate()
  .noPlus()

Array Schema

k.array(k.string())
  .minLength(1)
  .maxLength(10)
  .unique()

File Schema

k.file()
  .image()
  .maxSize(5 * 1024 * 1024)
  .extensions(['.jpg'])

Resources