@fantasizetech/fantasize-validation
v0.1.0
Published
Featherweight schema validation toolkit with Zod-like ergonomics and a tiny React form hook.
Maintainers
Readme
@fantasizetech/fantasize-validation
Featherweight schema validation with a Zod-style API, zero dependencies, and a tiny React form hook. Perfect when Yup/Zod are too heavy.
Features
- Minimal primitives:
string,number,email,record,array parse/safeParsewith structured issues andValidationError- Zero deps, tree-shakeable, works in Node + browser
- React hook
useValidationfor quick form validation without extra wiring
Install
npm i @fantasizetech/fantasize-validationPeer dependency:
npm i react react-domQuick Start
import { string, number, email, record, parse, safeParse } from '@fantasizetech/fantasize-validation';
const userSchema = record({
name: string({ minLength: 2 }),
age: number(),
email: email(),
});
// Throws on failure
const user = parse(userSchema, { name: 'Kai', age: 30, email: '[email protected]' });
// Safe alternative
const result = safeParse(userSchema, { name: 'K', age: 'not-a-number', email: 'nope' });
if (!result.success) {
console.log(result.error.issues);
// -> [{ path: ['age'], message: 'Expected number' }, { path: ['email'], message: 'Invalid email' }]
}Schemas
string(options?): validates strings, with optionalminLength,maxLength,trimnumber(): validates finite numbersemail(): validates email strings (trims first)array(itemSchema): validates arrays of the given schemarecord(shape): validates an object shape{ key: schema }
Helpers:
parse(schema, value): returns typed data or throwsValidationErrorsafeParse(schema, value): returns{ success: true, data }or{ success: false, error }
React Form Hook
useValidation keeps values + errors together and wires change/submit handlers.
import React from 'react';
import { string, email, record, useValidation } from '@fantasizetech/fantasize-validation';
const schema = record({
name: string({ minLength: 2 }),
email: email(),
});
export function SignupForm() {
const { values, errors, register, handleSubmit } = useValidation(schema, {
initialValues: { name: '', email: '' },
validateOnChange: true,
onSubmit: (data) => console.log('submit', data),
});
return (
<form onSubmit={handleSubmit()}>
<label>
Name
<input {...register('name')} />
{errors.name && <small>{errors.name}</small>}
</label>
<label>
Email
<input {...register('email')} />
{errors.email && <small>{errors.email}</small>}
</label>
<button type="submit">Create account</button>
</form>
);
}Hook API:
values: current form valueserrors: keyed by field or_rootregister(field): returns{ name, value, onChange }ready for inputssetField(key, value): set a single field (optionally re-validates)validate(nextValues?): run validation and populate errorshandleSubmit(fn?): returns submit handler; usesonSubmitfrom options if providedreset(nextValues?): reset values + clear errors
Error Shape
ValidationError.issues is an array:
type ValidationIssue = {
path: Array<string | number>; // e.g. ['address', 'city'] or [0, 'email']
message: string;
code?: string; // small hint like invalid_type | invalid_email
};Rationale
- Keep bundles tiny but ergonomic
- Favor readable error paths for form UX
- No runtime dependencies, just TypeScript + React peer
Engines
- Node:
>=20
