npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fantasizetech/fantasize-validation

v0.1.0

Published

Featherweight schema validation toolkit with Zod-like ergonomics and a tiny React form hook.

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 / safeParse with structured issues and ValidationError
  • Zero deps, tree-shakeable, works in Node + browser
  • React hook useValidation for quick form validation without extra wiring

Install

npm i @fantasizetech/fantasize-validation

Peer dependency:

npm i react react-dom

Quick 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 optional minLength, maxLength, trim
  • number(): validates finite numbers
  • email(): validates email strings (trims first)
  • array(itemSchema): validates arrays of the given schema
  • record(shape): validates an object shape { key: schema }

Helpers:

  • parse(schema, value): returns typed data or throws ValidationError
  • safeParse(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 values
  • errors: keyed by field or _root
  • register(field): returns { name, value, onChange } ready for inputs
  • setField(key, value): set a single field (optionally re-validates)
  • validate(nextValues?): run validation and populate errors
  • handleSubmit(fn?): returns submit handler; uses onSubmit from options if provided
  • reset(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