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

@pfeiferio/validator

v0.3.1

Published

TypeScript-first schema validation for APIs and forms with explicit parameters and async support

Readme

@pfeiferio/validator

npm types license downloads node

A small, TypeScript-first validation framework for APIs and forms.

It focuses on explicit parameters, schema-based validation, and full control over validation logic — including synchronous and asynchronous rules, nested objects, value transformation, and precise error paths.

If you prefer clarity over magic and want validation and transformation in one place, this library is for you.


Why this library exists

Most validation libraries optimize for brevity or implicit inference. @pfeiferio/validator optimizes for control and predictability.

  • No decorators
  • No hidden schema magic
  • No JSON Schema indirection

Instead, you explicitly define:

  • which parameters exist
  • when they are required
  • how they are validated
  • how values are transformed

This makes it especially well suited for backend APIs and complex request validation.


Installation

npm install @pfeiferio/validator

Quick Example

import {Schema, createParameter} from '@pfeiferio/validator'
import {checkString, checkNumber} from '@pfeiferio/check-primitives'

const name = createParameter('name')
  .validation(checkString)

const age = createParameter('age')
  .validation(checkNumber)

const schema = new Schema()
  .add(name)
  .add(age)

const result = schema.validate({name: 'Alice', age: 30})

if (result.errors.hasErrors()) {
  console.log(result.errors.errors)
} else {
  console.log(name.value, age.value)
}

Real-world Examples

Real-world usage examples can be found in the examples/ folder.

➡️ View examples

The examples demonstrate framework integrations, reusable parameter definitions and execution-node based validation logic.


Core Concepts

Parameters

A parameter represents a single input value.

Parameters:

  • can be required or optional
  • validate and transform values
  • can be synchronous or asynchronous
  • support arrays and nested objects
  • expose their sanitized value after validation
const email = createParameter('email')
  .validation(value => value.toLowerCase())

Async validation:

const username = createParameter('username')
  .asyncValidation(async value => {
    await checkAvailability(value)
    return value
  })

Schema

A schema groups parameters and controls validation execution.

const schema = new Schema()
  .add(param1)
  .add(param2)

Validation:

const result = schema.validate(data)

data can be:

  • a plain object
  • a SearchStore (advanced use)

Schemas automatically handle sync and async parameters. If async validation is involved, validate() returns a Promise.


Advanced Examples

Working with Arrays and Nested Objects

You can validate arrays of objects and access individual nodes in the execution tree:

import {createParameter, Schema} from '@pfeiferio/validator'

const age = createParameter('age').noValidation()
const name = createParameter('name').noValidation()

const user = createParameter('user')
  .object({age, name})
  .many()

const schema = new Schema()
const result = await schema.add(user).validate({
  user: [
    {age: 18, name: 'max'},
    {age: 20, name: 'ben'},
    {age: 22, name: 'johnny'}
  ]
})

// Access all user nodes
result.nodes(user).map(node => node.value)
// → [{ age: 18, name: 'max' }, { age: 20, name: 'ben' }, { age: 22, name: 'johnny' }]

// Access all age values
result.nodes(age).map(node => node.value)
// → [18, 20, 22]

// Access first age
result.nodes(age).at(0)?.value
// → 18

// Access last age
result.nodes(age).at(-1)?.value
// → 22

Conditional Requirements with requiredIf

You can define dynamic requirements based on other field values using the execution tree:

import {createParameter, Schema} from '@pfeiferio/validator'

const age = createParameter('age').noValidation()
const name = createParameter('name').noValidation()

const parentName = createParameter('parentName', false)
  .requiredIf((sanitizedValues, node, requiredIfCtx) => {
    const ageNode = node.siblings(age).at(0)

    if (!ageNode || ageNode.value >= 18) {
      return false
    }

    requiredIfCtx
      .dependsOn(ageNode)
      .reason('age.min.18')

    return true
  })
  .noValidation()

const user = createParameter('user')
  .object({age, name, parentName})
  .many()

const schema = new Schema()
const result = await schema.add(user).validate({
  user: [
    {age: 37, name: 'max'},
    {age: 14, name: 'ben'},           // Missing parentName → ERROR
    {age: 22, name: 'johnny'}
  ]
})

console.log(result.errors.errors)
/**
 * [
 *   {
 *     path: 'user.1.parentName',
 *     name: 'parentName',
 *     reason: 'required.if',
 *     context: {
 *       dependsOn: ['user.1.age'],
 *       reasons: ['age.min.18']
 *     }
 *   }
 * ]
 */

SearchStore (advanced)

SearchStore is a thin abstraction over input data with helper methods like get() and has().

import {SearchStore} from '@pfeiferio/validator'

const store = new SearchStore(req.body)
schema.validate(store)

Using plain data is recommended unless you need advanced control.


Error Handling

Validation errors include precise paths, making them easy to map back to APIs or UIs.

{
  path: 'user.email',
    name
:
  'email',
    reason
:
  'email.invalidFormat'
}

For conditional requirements, errors include context about dependencies:

{
  path: 'user.1.parentName',
    name
:
  'parentName',
    reason
:
  'required.if',
    context
:
  {
    dependsOn: ['user.1.age'],
      reasons
  :
    ['age.min.18']
  }
}

Sync vs Async

Parameters can be synchronous or asynchronous.

The schema automatically detects async usage and behaves accordingly.

Helper guards are available:

import {
  isParameter,
  isParameterSync,
  isParameterAsync
} from '@pfeiferio/validator'

When to use this library

  • You want full control over validation logic
  • You need async validation (e.g. database checks)
  • You validate complex, nested request payloads
  • You want validation and transformation in one step
  • You need access to the validation execution tree (for cross-field validation)

When not to use it

  • You only need simple form validation
  • You want automatic schema inference
  • You prefer JSON Schema–based tooling

Documentation

Advanced examples and internal concepts can be found in:

/docs

Related Packages

  • @pfeiferio/check-primitives – primitive validation helpers

License

MIT