drizzle-zod-codegen
v0.1.0
Published
Generate static Zod schema files from Drizzle ORM schemas
Maintainers
Readme
drizzle-zod-codegen
Generate static Zod schema files from Drizzle ORM schemas.
Why?
drizzle-zod creates Zod schemas at runtime, which is great for many use cases. However, static generated files offer several advantages:
- Inspectable: Easy to see exactly what schemas you have
- Version controllable: Track changes in git
- No runtime overhead: Schemas are pre-generated
- Better tree-shaking: Only import what you need
- Easier to customize: Modify generated files if needed
Features
- ✅ Full parity with drizzle-zod: Uses the same mapping logic
- ✅ All dialects supported: PostgreSQL, MySQL, SQLite, SingleStore
- ✅ Complete type coverage: All column types, enums, views
- ✅ Smart schema generation:
SelectSchema- for query resultsInsertSchema- for inserts (excludes generated columns, makes defaults optional)UpdateSchema- for updates (all fields optional)
- ✅ Flexible discovery: Config file, directory scanning, or explicit paths
- ✅ CLI and programmatic API
Installation
npm install -D drizzle-zod-codegen
# or
pnpm add -D drizzle-zod-codegenUsage
CLI
# Generate from specific files
drizzle-zod-codegen generate src/schema.ts
# Scan a directory
drizzle-zod-codegen generate --dir src/db
# Use drizzle.config.ts/js/mts/mjs
drizzle-zod-codegen generate --config drizzle.config.ts
# Custom pattern
drizzle-zod-codegen generate --dir src --pattern "**/*.model.ts"
# Emit every schema into a single bundle file
drizzle-zod-codegen generate src/**/*.schema.ts --output single --out ./schemas/all.zod.ts
# Emit one file per Drizzle entity
drizzle-zod-codegen generate src/schema.ts --output per-schema --out-dir ./generated-schemas
#### Additional Flags
- `--no-cache` – force `bundle-require` to rebundle each schema/config file instead of reusing a module cache entry, helpful when you run the generator repeatedly in the same process (watch mode or a scripted loop).Output Modes
per-file(default) – writes one.zodfile next to each schema (or mirrors into--out-dir).per-schema– writes one file per table/view/enum named{Entity}.zod.ts. Combine with--out-dirto collect them.single– aggregates every generated schema into the file provided via--out.
Programmatic API
import { generateZodSchemas, discoverSchemaFiles, runGenerateCommand } from 'drizzle-zod-codegen';
// Discover schema files
const schemaFiles = await discoverSchemaFiles({
scanDir: 'src/db',
pattern: '**/*.schema.ts',
});
// Generate for each file
for (const file of schemaFiles) {
await generateZodSchemas({
inputPath: file.path,
outputPath: file.outputPath,
});
}
// Or aggregate everything into a single file via runGenerateCommand
await runGenerateCommand({
files: schemaFiles.map(file => file.path),
mode: 'single',
outFile: './all-schemas.zod.ts',
});Pass forceRefreshModuleCache: true to generateZodSchemas() if you want to clear the loader cache before each invocation (useful for watch scripts that regenerate files without restarting the node process).
TypeScript Support
Schema and config files are bundled through esbuild at runtime, so TypeScript enums, satisfies, const assertions, and other non-JavaScript syntax work without extra loaders.
Example
Given this Drizzle schema:
// users.schema.ts
import { pgTable, serial, text, integer, timestamp } from 'drizzle-orm/pg-core';
export const users = pgTable('users', {
id: serial('id').primaryKey(),
name: text('name').notNull(),
email: text('email').notNull(),
age: integer('age'),
createdAt: timestamp('created_at').notNull().defaultNow(),
});Running drizzle-zod-codegen generate users.schema.ts generates:
// users.zod.ts
import { z } from 'zod';
export const UsersSelectSchema = z.object({
id: z.number().int().gte(-2147483648).lte(2147483647),
name: z.string(),
email: z.string(),
age: z.number().int().gte(-2147483648).lte(2147483647).nullable(),
createdAt: z.date()
});
export const UsersInsertSchema = z.object({
id: z.number().int().gte(-2147483648).lte(2147483647).optional(),
name: z.string(),
email: z.string(),
age: z.number().int().gte(-2147483648).lte(2147483647).nullable().optional(),
createdAt: z.date().optional()
});
export const UsersUpdateSchema = z.object({
id: z.number().int().gte(-2147483648).lte(2147483647).optional(),
name: z.string().optional(),
email: z.string().optional(),
age: z.number().int().gte(-2147483648).lte(2147483647).nullable().optional(),
createdAt: z.date().optional()
});Output Naming
- Tables:
{PascalCase}SelectSchema,{PascalCase}InsertSchema,{PascalCase}UpdateSchema - Views:
{PascalCase}SelectSchema - Enums:
{PascalCase}Schema
Supported Features
Column Types
- All numeric types (with proper min/max validation)
- Strings (with length constraints)
- Dates & timestamps
- Booleans
- JSON & JSONB
- Arrays
- UUIDs
- Enums
- Geometry types (PostGIS)
- Buffers
- Custom types
Schema Features
- Primary keys
- Not null constraints
- Default values
- Generated columns (excluded from insert/update)
- Nullable columns
- Views (including nested selections)
- PostgreSQL enums
Discovery Options
1. Explicit Files (CLI)
drizzle-zod-codegen generate src/users.schema.ts src/posts.schema.ts2. Directory Scanning
drizzle-zod-codegen generate --dir src/db --pattern "**/*.schema.ts"Default pattern: **/*.schema.{ts,js,mts,mjs,cts,cjs}
3. Drizzle Config
// drizzle.config.ts
export default {
schema: './src/db/schema.ts',
// or multiple files
schema: ['./src/db/users.ts', './src/db/posts.ts'],
// or glob pattern
schema: './src/db/**/*.schema.ts',
};Then run:
drizzle-zod-codegen generateTroubleshooting
- Aggregate export errors – When serialization fails for a table, view, or enum export the generator throws an
AggregateError; the CLI printsOne or more exports failed to process:followed by each export's message so you can fix the offending export before retrying. - Schema cache misbehavior – Include the
--no-cacheflag when you run the generator repeatedly in the same process to forcebundle-requireto rebundle every schema/config file instead of reusing cached modules.
Output Files
By default, generates one .zod.ts file per schema file:
src/db/schema.ts→src/db/schema.zod.tsusers.schema.ts→users.zod.ts
Comparison with drizzle-zod
| Feature | drizzle-zod | drizzle-zod-codegen | |---------|------------|---------------------| | Schema generation | Runtime | Static files | | Type coverage | ✅ Complete | ✅ Complete | | All dialects | ✅ | ✅ | | Refinements | ✅ | ⏳ Planned | | Custom Zod instance | ✅ | ⏳ Planned | | Coercion | ✅ | ⏳ Planned | | File size | Small | Larger (explicit schemas) | | Inspectable | ❌ | ✅ | | Customizable output | ❌ | ✅ | | Build step required | ❌ | ✅ |
License
MIT
Credits
Built using the same column mapping logic as drizzle-zod to ensure 100% compatibility.
