Generate native Zod schemas and database constraints from Drizzle table definitions. No additional runtime bundle.
npm install drizzle-to-zod-cli
# or
bun install drizzle-to-zod-cli
# or
yarn add drizzle-to-zod-cliThe CLI provides two main commands:
drizzle-to-zod constraints <tables-file> <output-file>Example:
drizzle-to-zod constraints src/schema/tables.ts src/schema/constraints.tsThis generates database constraint constants from your Drizzle table definitions, useful for error handling and constraint violations.
drizzle-to-zod schemas <tables-file> <output-file> [options]--select=true- Enable select schemas (default if no flags specified)--insert=true- Enable insert schemas--update=true- Enable update schemas--select=false- Disable select schemas--insert=false- Disable insert schemas--update=false- Disable update schemas
# Generate only select schemas (default)
drizzle-to-zod schemas src/schema/tables.ts src/schema/schemas.ts
# Generate select and insert schemas
drizzle-to-zod schemas src/schema/tables.ts src/schema/schemas.ts --select=true --insert=true
# Generate all schema types
drizzle-to-zod schemas src/schema/tables.ts src/schema/schemas.ts --select=true --insert=true --update=true
# Generate only insert and update schemas
drizzle-to-zod schemas src/schema/tables.ts src/schema/schemas.ts --select=false --insert=true --update=true- ✅ Supports all Drizzle column types
- ✅ Handles enum types and imports
- ✅ Processes JSONB fields with TypeScript type annotations
- ✅ Generates appropriate nullable/optional fields based on schema type
- ✅ Primary key and unique constraint detection
- ✅ Composite primary keys support
- ✅ Zero runtime dependencies for generated schemas
For reading data from the database. Fields are typed as they exist in the database.
For creating new records. Nullable fields and timestamp fields (createdAt, updatedAt, deletedAt) become optional.
For updating existing records. All fields except id become optional.
Given a Drizzle table definition:
export const users = pgTable("users", {
id: serial("id").primaryKey(),
email: text("email").notNull().unique(),
name: text("name"),
createdAt: timestamp("created_at").defaultNow().notNull(),
})The CLI generates:
import { z } from "zod"
export const usersSelectSchema = z.object({
id: z.number().int(),
email: z.string(),
name: z.string().nullable(),
createdAt: z.string(),
})
export const usersInsertSchema = z.object({
id: z.number().int(),
email: z.string(),
name: z.string().nullable().optional(),
createdAt: z.string().optional(),
})
export const usersUpdateSchema = z.object({
email: z.string().optional(),
name: z.string().nullable().optional(),
createdAt: z.string().optional(),
})If you were previously using the scripts directly:
# Old way
bunx ts-node scripts/db.store.generate-constraints.script.js src/architecture/db.store.tables.ts src/architecture/db.store.constraints.ts
# New way
drizzle-to-zod constraints src/architecture/db.store.tables.ts src/architecture/db.store.constraints.ts# Old way
bunx ts-node scripts/db.store.generate-schemas.script.js src/architecture/db.store.tables.ts src/architecture/db.store.schemas.ts --select=true --insert=true --update=true
# New way
drizzle-to-zod schemas src/architecture/db.store.tables.ts src/architecture/db.store.schemas.ts --select=true --insert=true --update=true