---
title: "Zod Validation"
description: "Zod Validation provides a bridge between Drizzle ORM database definitions and Zod schemas, enabling automatic generation of validation logic from table and view definitions. By introspecting the Dr..."
last_updated: "2026-07-02T09:35:18.999626+00:00"
canonical_url: "https://www.doc0.dev/docs/e1b68fed-3c4e-4c95-b2ba-ebf050f78025/technical/schema-integrations/zod-validation"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [drizzle-kit/src/introspect-pg.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-kit/src/introspect-pg.ts)
- [drizzle-kit/src/introspect-gel.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-kit/src/introspect-gel.ts)
- [drizzle-kit/src/serializer/pgSchema.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-kit/src/serializer/pgSchema.ts)
- [drizzle-valibot/src/column.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-valibot/src/column.ts)
- [drizzle-typebox/src/column.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-typebox/src/column.ts)
- [drizzle-zod/src/column.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-zod/src/column.ts)
- [drizzle-kit/src/serializer/gelSchema.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-kit/src/serializer/gelSchema.ts)
- [drizzle-zod/src/schema.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-zod/src/schema.ts)
- [drizzle-orm/type-tests/pg/tables.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/type-tests/pg/tables.ts)
</details>

Zod Validation provides a bridge between Drizzle ORM database definitions and Zod schemas, enabling automatic generation of validation logic from table and view definitions. By introspecting the Drizzle schema, this component generates Zod schemas that represent the structure of your database, ensuring type safety and input validation throughout the application lifecycle.

The system solves the problem of manual schema synchronization, where changes to the database structure would otherwise require tedious updates to validation layers. It provides specialized functions to create "select", "insert", and "update" schemas, which apply different rules regarding nullability and optionality based on the Drizzle column configuration.

Designed for tight integration with the Drizzle ecosystem, the subsystem leverages column metadata (such as data types, nullability, and default values) to construct the corresponding Zod types. This approach prevents runtime errors by ensuring that data interacting with the database adheres strictly to the defined schema at the application boundaries.

## Core Transformation Logic

The transformation logic centers on mapping Drizzle column types to their equivalent Zod schema definitions. The `columnToSchema` function serves as the central dispatcher, inspecting column characteristics to decide the appropriate Zod validator.

It handles complex types by recursively calling itself for arrays or inspecting object-specific properties for types like points, lines, and geometry. The mechanism relies on `isColumnType` and `isWithEnum` to differentiate between standard and specialized column types, ensuring that even custom extensions are handled correctly.

Sources: [drizzle-zod/src/column.ts:70-135](https://github.com/blade47/drizzle-orm/blob/main/drizzle-zod/src/column.ts#L70-L135)

## Schema Generation Pipeline

The generation of schemas (`createSelectSchema`, `createInsertSchema`, `createUpdateSchema`) is managed by `handleColumns`. This function iterates over a table's columns and applies conditional logic to ensure the schema matches the required database operation.

The pipeline processes each column by:
1. Checking if the column should be excluded via the `conditions` logic.
2. Converting the column to its base Zod schema.
3. Applying refinements if custom validation is provided by the user.
4. Applying nullability or optionality decorators based on column properties (e.g., `notNull` vs. default values).

Sources: [drizzle-zod/src/schema.ts:19-64](https://github.com/blade47/drizzle-orm/blob/main/drizzle-zod/src/schema.ts#L19-L64)

```mermaid
flowchart TD
    A["getTableColumns(table)"] --> B["handleColumns(columns, refinements, conditions)"]
    B --> C["Loop over columns"]
    C --> D{"Column<br>included?"}
    D -- Yes --> E["columnToSchema(column)"]
    E --> F["Apply optional/nullable<br>decorators"]
    F --> G["Return z.object"]
    D -- No --> H["Skip column"]
```
Sources: [drizzle-zod/src/schema.ts:15-64](https://github.com/blade47/drizzle-orm/blob/main/drizzle-zod/src/schema.ts#L15-L64)

## Handling Conditions

The `Conditions` interface dictates how `handleColumns` modifies the schema for different database actions. These conditions are defined as sets of functions (`never`, `optional`, `nullable`) that act as guards.

- **Select:** Makes columns nullable if `!notNull`.
- **Insert:** Excludes `generated` columns, makes columns with defaults `optional`, and makes `!notNull` columns `nullable`.
- **Update:** Excludes `generated` columns and treats all columns as `optional`.

Sources: [drizzle-zod/src/schema.ts:76-92](https://github.com/blade47/drizzle-orm/blob/main/drizzle-zod/src/schema.ts#L76-L92)

## Handling Numeric Types

Numeric and bigint column conversion includes built-in range validation. The `numberColumnToSchema` and `bigintColumnToSchema` functions extract constraints from Drizzle's internal metadata and apply Zod's `gte()` and `lte()` checks.

> [!NOTE]
> The generation logic checks for `unsigned` SQL types to adjust the `min` value constraint automatically, ensuring generated schemas are as restrictive as the underlying database type.

Sources: [drizzle-zod/src/column.ts:137-265](https://github.com/blade47/drizzle-orm/blob/main/drizzle-zod/src/column.ts#L137-L265)

## API Usage

Developers can use the high-level API to generate schemas directly from Drizzle table objects. The factory pattern allows for additional configuration, such as coercion of primitive types.

```typescript
import { pgTable, serial, text, integer } from 'drizzle-orm/pg-core';
import { createInsertSchema, createSelectSchema } from 'drizzle-zod';

const users = pgTable('users', {
  id: serial('id').primaryKey(),
  name: text('name').notNull(),
  age: integer('age'),
});

const insertUserSchema = createInsertSchema(users);
const selectUserSchema = createSelectSchema(users);
```
Sources: [drizzle-zod/src/schema.ts:94-119](https://github.com/blade47/drizzle-orm/blob/main/drizzle-zod/src/schema.ts#L94-L119)

## Schema Factory

The `createSchemaFactory` provides a way to globally configure coercion behavior. When the factory is initialized with `coerce: true`, generated schemas will automatically add Zod's coercion layers for primitives, which is useful when dealing with form data or query parameters.

Sources: [drizzle-zod/src/schema.ts:121-152](https://github.com/blade47/drizzle-orm/blob/main/drizzle-zod/src/schema.ts#L121-L152)

## Related

- [Schema Declarations](https://www.doc0.dev/docs/e1b68fed-3c4e-4c95-b2ba-ebf050f78025/technical/database-schema/schema-declarations)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/e1b68fed-3c4e-4c95-b2ba-ebf050f78025/llms.txt) for all pages in this wiki.
