---
title: Create Validators
description: Build reusable validation functions with createStandardValidator and createStandardValidatorSync.
type: package
package: "@zap-studio/validation"
---

When the same schema is reused across many calls, bind it once with a factory and share the resulting validator function.

## Why Create Validator Functions?

Use the factories when you want:

- a reusable validator for a specific schema
- separation between schema setup and runtime calls
- consistent behavior across multiple modules
- to avoid passing the schema at every call site in performance-sensitive paths

All examples use this schema:

```ts
import { z } from "zod";

const userSchema = z.object({
  name: z.string(),
  age: z.number(),
});
```

## Create an Async Validator

`createStandardValidator(schema)` returns an async validator that works with both sync and async schemas. It supports the same options and return modes as `standardValidate`.

```ts
import { createStandardValidator } from "@zap-studio/validation";

const validateUser = createStandardValidator(userSchema);

// Non-throwing mode (default): raw result with `value` or `issues`
const result = await validateUser({ name: "Ada", age: 37 });

if (result.issues) {
  console.error("Validation failed", result.issues);
} else {
  console.log("Validation passed", result.value);
}

// Throwing mode: parsed value, throws ValidationError on failure
const user = await validateUser(input, { throwOnError: true });
```

Use it when:

- your call sites are async
- schema behavior might become async over time
- you want one reusable validator instance

## Create a Sync Validator

`createStandardValidatorSync(schema)` returns a synchronous validator. It supports the same options and return modes as `standardValidateSync`.

```ts
import { createStandardValidatorSync } from "@zap-studio/validation";

const validateUser = createStandardValidatorSync(userSchema);

const result = validateUser({ name: "Ada", age: 37 });

if (result.issues) {
  console.error("Validation failed", result.issues);
} else {
  console.log("Validation passed", result.value);
}

const user = validateUser(input, { throwOnError: true });
```

Use it when:

- code must stay synchronous
- schemas are guaranteed sync

:::warning[Async Schemas]

If the schema validates asynchronously, the returned validator throws an `Error` with the message `Async schemas are not supported by createStandardValidatorSync`. The underlying `TypeError` is attached as the error's `cause`.

:::

## Which Factory Should I Use?

- Prefer `createStandardValidator` for default package and app code.
- Use `createStandardValidatorSync` in strict sync contexts only.
- For one-shot validation without a reusable function, call [`standardValidate`](/validation/async-validation) or [`standardValidateSync`](/validation/synchronous-validation) directly.
