valorm
v3.1.0
Published
Valorm is a lightweight TypeScript-first validation library for parsing unknown input into safe, typed data.
Readme
🚀 Valorm
Valorm is a lightweight, TypeScript-first validation library for turning unknown data into safe, typed data.
Think of it like:
“Take messy input → validate it → get clean, typed output.”
🪶 Why Valorm?
Valorm is built for modern apps that need validation without bloat.
🪶 Lightweight Alternative to Zod
- Tiny bundle size (~2.6KB gzipped)
- Minimal runtime overhead
- No unnecessary abstractions
⚡ Fast Validation for Modern Apps
- Optimized parsing pipeline
- Efficient runtime checks
- Great for frontend + serverless environments
🧩 Minimal, Yet Powerful
Valorm gives you only what you actually need:
- Chainable schemas
- Strong TypeScript inference
- Safe parsing APIs
- Flexible composition
Nothing extra. Nothing heavy.
📦 Installation
npm install valorm
# or
pnpm add valorm
# or
bun add valorm⚡ Quick Start
TypeScript
import { v, Infer } from "valorm";
const UserSchema = v.object({
id: v.string().uuid(),
email: v.string().trim().email(),
age: v.number().int().nonnegative().optional(),
isAdmin: v.boolean().default(false),
});
type User = Infer<typeof UserSchema>;
const user = UserSchema.parse({
id: "550e8400-e29b-41d4-a716-446655440000",
email: " [email protected] ",
});
console.log(user);JavaScript
import { v } from "valorm";
const UserSchema = v.object({
email: v.string().email(),
});
const result = UserSchema.safeParse({ email: "bad-email" });
if (!result.success) {
console.log(result.error.issues);
}🧠 Core Concepts
parse()
- Returns validated data
- Throws on failure
schema.parse(data);safeParse()
- Never throws
- Returns structured result
const result = schema.safeParse(data);
if (!result.success) {
console.log(result.error);
}Infer
Extracts the TypeScript type from a schema.
type User = Infer<typeof UserSchema>;🔤 Primitive Schemas
v.string()
v.string().min(3).max(20).email();Methods:
coerce()trim()min(),max(),length()email(),url(),uuid()regex()startsWith(),endsWith()nonempty()
v.number()
v.number().int().positive();Methods:
coerce()min(),max(),gt(),lt()int(),positive(),negative(),nonnegative()multipleOf()
v.boolean()
v.boolean().coerce();Supports:
"true","false"1,0
v.date()
v.date().min(new Date("2026-01-01"));Accepts:
- Date
- string
- timestamp
v.literal(value)
v.literal("admin");v.enum([...])
v.enum(["draft", "published"] as const);v.any() / v.unknown()
Accepts anything.
v.never()
Always fails validation.
🧩 Object & Complex Schemas
v.object()
const User = v.object({
id: v.string(),
email: v.string().email(),
});Modes
- default → strips unknown keys
strict()→ throws on unknown keyspassthrough()→ keeps unknown keys
Utilities
User.pick("id");
User.omit("email");
User.partial();
User.extend({ age: v.number() });
User.merge(OtherSchema);Arrays
v.array(v.string()).min(1).max(10);Tuples
v.tuple([v.number(), v.number()]);Records
v.record(v.number());Unions
v.union([v.string(), v.number()]);Discriminated Unions
v.discriminatedUnion("type", [
v.object({ type: v.literal("a") }),
v.object({ type: v.literal("b") }),
]);Intersections
v.intersection(A, B);🔧 Shared Modifiers
Works on all schemas:
optional()
v.string().optional();nullable()
v.string().nullable();default()
v.number().default(10);refine()
v.number().refine(n => n % 2 === 0, "Must be even");transform()
v.string().transform(s => s.toUpperCase());❌ Error Handling
import { ValidationError } from "valorm";
try {
schema.parse(data);
} catch (err) {
if (err instanceof ValidationError) {
console.log(err.issues);
}
}Issue Shape
{
path: (string | number)[];
message: string;
received?: unknown;
}📊 Benchmarks
Comparison with Zod:
Bundle Size
| Library | Gzipped | | ------- | ------------- | | Valorm | ~2.6KB 🪶 | | Zod | ~59KB |
Performance (Conceptual)
| Operation | Valorm | Zod | | ----------------- | ------------- | --------- | | Simple validation | ⚡ Fast | ⚡ Fast | | Object parsing | ⚡ Lightweight | ⚡ Heavier | | Cold start | 🪶 Low impact | 📈 Higher |
Summary
- 🪶 Smaller footprint
- ⚡ Fast validation
- 🧩 Minimal API
- 🚀 Modern app focused
🔥 Full Example
const Post = v.object({
title: v.string().min(3),
body: v.string().min(20),
status: v.enum(["draft", "published"]).default("draft"),
tags: v.array(v.string()).default(() => []),
});
const result = Post.safeParse({
title: "Hello",
body: "This is a valid post body...",
});
if (result.success) {
console.log(result.data);
}⚠️ Current Notes
- Object schemas strip unknown keys by default
nullable()behavior may evolve- Some custom messages still improving (WIP)
📦 Exports
v→ schema builderSchema→ base classValidationErrorInfer<T>
🛠 Development
npm run build
npm run typecheck🧭 Final Thoughts
Valorm is built for:
- ⚡ speed
- 🧠 clarity
- 😎 developer experience
If you know Zod, you’ll feel right at home — just lighter, faster, and simpler.
🚀 Philosophy
Do less. Stay fast. Keep it simple.
