pgzod - PostgreSQL to Zod Schema Generator
raw JSON →pgzod is a command-line utility for generating TypeScript-first Zod schemas and types directly from a live PostgreSQL database schema. It aims to synchronize your application's data validation and typing with your database structure, reducing manual effort and potential mismatches. The current stable version is 3.3.0, with minor and patch releases occurring regularly based on feature additions and bug fixes. Key differentiators include its focused integration with PostgreSQL, leveraging Zod for robust validation, and the ability to define different 'strategies' (like `write` or `readwrite`) for schema generation based on usage context. While primarily a CLI tool, it also offers a programmatic API for direct integration into Node.js applications, supporting database connection details via environment variables or configuration objects, making it suitable for both local development and CI/CD pipelines.
Common errors
error Error: connect ECONNREFUSED <DB_HOST>:<DB_PORT> ↓
PGHOST, PGPORT, PGUSER, PGPASSWORD, and PGDATABASE environment variables (or corresponding command-line options/config properties) are correct. Ensure the database server is running and accessible from the machine where pgzod is executed, and check for any firewall restrictions. error No tables found in the provided schema: 'your_schema_name' ↓
--schema option or Config.schema) actually contains tables you intend to generate Zod schemas for. error ZodError: Invalid input (when validating data with pgzod-generated schemas) ↓
generated_schemas.ts). Ensure your input data matches the expected types, required fields, and constraints. Pay particular attention to changes in pgzod v3.0.1 regarding foreign key optionality, which might require adjustments to your input data or validation logic. Warnings
breaking pgzod v3.0.0 introduced support for generated columns. While this is a feature, it represents a significant change in how schemas are processed and might affect existing generated schemas if not handled, particularly if you were previously working around the lack of support. ↓
breaking In v3.0.1, pgzod changed its default behavior, no longer marking foreign keys as strictly required. This alters the generated Zod schema for relationships, potentially making fields that were implicitly required optional. ↓
breaking Node.js v12 support was officially dropped in pgzod v2.1.1. Users on older Node.js versions must upgrade to at least Node.js 14 (or newer supported LTS versions) to use pgzod v2.1.1 and beyond. ↓
gotcha By default, pgzod will only process tables within the 'public' schema of your PostgreSQL database. If your tables are organized into a different schema (e.g., 'app', 'private'), pgzod will not find them without explicit instruction. ↓
Install
npm install pgzod yarn add pgzod pnpm add pgzod Imports
- generateZodSchemas wrong
const generateZodSchemas = require('pgzod');correctimport { generateZodSchemas } from 'pgzod'; - Config wrong
import { Config } from 'pgzod';correctimport type { Config } from 'pgzod'; - getConfig wrong
import getConfig from 'pgzod';correctimport { getConfig } from 'pgzod';
Quickstart
import { generateZodSchemas, type Config } from 'pgzod';
import * as path from 'path';
import * as fs from 'fs'; // Required for fs.existsSync to check output, but not strictly for pgzod itself.
async function main() {
// Ensure your .env file or environment variables are set:
// PGHOST=localhost
// PGPORT=5432
// PGUSER=postgres
// PGPASSWORD=mysecretpassword
// PGDATABASE=your_database_name
// PGSCHEMA=public
const outputFilePath = path.join(__dirname, 'generated_schemas.ts');
const config: Config = {
host: process.env.PGHOST ?? 'localhost',
port: parseInt(process.env.PGPORT ?? '5432', 10),
user: process.env.PGUSER ?? 'postgres',
password: process.env.PGPASSWORD ?? 'mysecretpassword',
database: process.env.PGDATABASE ?? 'your_database_name',
schema: process.env.PGSCHEMA ?? 'public',
output: outputFilePath,
strategy: 'readwrite', // Options: 'write' or 'readwrite'
// customZodTypes: { // Example for mapping custom PostgreSQL types
// 'jsonb': 'z.any()',
// },
};
try {
console.log(`Attempting to generate Zod schemas from DB '${config.database}' (schema: '${config.schema}')...`);
await generateZodSchemas(config);
console.log(`Successfully generated Zod schemas to: ${outputFilePath}`);
// To demonstrate usage of generated schemas (requires a 'user' table in your DB)
// if (fs.existsSync(outputFilePath)) {
// const { UserReadSchema } = await import(outputFilePath); // Adjust based on your table names
// console.log("Example UserReadSchema shape:", UserReadSchema.shape);
// }
} catch (error) {
console.error("Failed to generate Zod schemas:", error);
process.exit(1);
}
}
main();