Zodipus setup
Install and configure Zodipus Prisma generator. Use when installing zodipus, setting up generator options, configuring output paths, choosing date formats, or integrating with Next.js/Express/Fastify/tRPC.From its SKILL.md
npx -y skills add bratsos/zodipus --skill zodipus-setupAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its file declares
Copied from the file, not written here
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
7.8 KB, as published. Nobody here has run it
Zodipus Setup
Complete guide for installing and configuring Zodipus.
When to Apply
- User is installing zodipus for the first time
- User asks about generator configuration options
- User needs framework-specific setup (Next.js, Express, tRPC)
- User wants to understand dateFormat, relationDepth, or other options
- User is setting up a new Prisma project with Zod validation
Installation
# npm
npm install zodipus zod
# pnpm
pnpm add zodipus zod
# yarn
yarn add zodipus zod
Requirements:
- Node.js 18+
- Prisma 6.0+
- Zod 3.25.0+
Basic Configuration
Add to your schema.prisma:
generator client {
provider = "prisma-client-js"
}
generator zodipus {
provider = "zodipus"
output = "./generated"
}
model User {
id String @id @default(cuid())
email String @unique
name String?
role Role @default(USER)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
posts Post[]
}
model Post {
id String @id @default(cuid())
title String
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId String
}
enum Role {
USER
ADMIN
}
Generate Schemas
npx prisma generate
This creates:
generated/
├── enums.ts # RoleSchema
├── models.ts # UserSchema, PostSchema
├── custom-schemas.ts # Placeholder for @zodSchema
├── generated-relations.ts
└── generated-index.ts
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
provider | string | Required | Must be "zodipus" |
output | string | Required | Output directory for generated files |
relationDepth | string | "5" | Maximum depth for nested relation extraction |
dateFormat | string | "coerce" | DateTime handling: "coerce" or "string" |
passthroughEnabled | string | "false" | Allow unknown keys in objects |
debug | string | "false" | Enable verbose debug logging |
zodImport | string | "zod" | Custom Zod import path |
Date Format Options
dateFormat = "coerce" (Default)
Accepts multiple input types, converts to Date:
// All valid inputs:
UserSchema.parse({ createdAt: new Date() }); // Date object
UserSchema.parse({ createdAt: '2024-01-15T10:30:00Z' }); // ISO string
UserSchema.parse({ createdAt: 1705315800000 }); // Timestamp
Use when: Receiving data from various sources (APIs, databases, user input).
dateFormat = "string"
Requires strict ISO 8601 format:
// Only ISO strings accepted:
UserSchema.parse({ createdAt: '2024-01-15T10:30:00.000Z' }); // OK
UserSchema.parse({ createdAt: new Date() }); // Error!
Use when: Building strict APIs, need consistent date format.
Passthrough Mode
passthroughEnabled = "false" (Default)
Unknown keys are stripped:
const data = { id: '1', email: '[email protected]', unknownField: 'ignored' };
const user = UserSchema.parse(data);
// user = { id: '1', email: '[email protected]' } - unknownField removed
Use when: Sanitizing input, preventing data leakage.
passthroughEnabled = "true"
Unknown keys are preserved:
const data = { id: '1', email: '[email protected]', extra: 'kept' };
const user = UserSchema.parse(data);
// user = { id: '1', email: '[email protected]', extra: 'kept' }
Use when: Transforming data, need to preserve extra fields.
Relation Depth
Controls how deeply nested relations are extracted for the Query Engine:
generator zodipus {
relationDepth = "10" # Allow queries 10 levels deep
}
Default: 5 - Sufficient for most apps. Increase if you have deeply nested queries.
Common Configurations
Strict API Server
Best for REST/GraphQL APIs with strict validation:
generator zodipus {
provider = "zodipus"
output = "./src/generated/zodipus"
passthroughEnabled = "false"
dateFormat = "string"
relationDepth = "5"
}
Flexible Data Pipeline
Best for ETL, migrations, or internal tools:
generator zodipus {
provider = "zodipus"
output = "./generated"
passthroughEnabled = "true"
dateFormat = "coerce"
relationDepth = "8"
}
Minimal Setup
Quick start with sensible defaults:
generator zodipus {
provider = "zodipus"
output = "./generated"
}
Framework Integration
Next.js App Router
// app/api/users/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { UserSchema } from '@/generated';
import { prisma } from '@/lib/prisma';
export async function POST(request: NextRequest) {
const body = await request.json();
const result = UserSchema.omit({ id: true, createdAt: true, updatedAt: true })
.safeParse(body);
if (!result.success) {
return NextResponse.json({ errors: result.error.flatten() }, { status: 400 });
}
const user = await prisma.user.create({ data: result.data });
return NextResponse.json(UserSchema.parse(user));
}
Express.js
// routes/users.ts
import { Router } from 'express';
import { UserSchema } from '../generated';
import { prisma } from '../lib/prisma';
const router = Router();
router.post('/', async (req, res) => {
const CreateUserSchema = UserSchema.omit({ id: true, createdAt: true, updatedAt: true });
const result = CreateUserSchema.safeParse(req.body);
if (!result.success) {
return res.status(400).json({ errors: result.error.flatten() });
}
const user = await prisma.user.create({ data: result.data });
res.json(UserSchema.parse(user));
});
export default router;
tRPC
// server/routers/user.ts
import { router, publicProcedure } from '../trpc';
import { UserSchema } from '../../generated';
import { prisma } from '../../lib/prisma';
export const userRouter = router({
create: publicProcedure
.input(UserSchema.omit({ id: true, createdAt: true, updatedAt: true }))
.mutation(async ({ input }) => {
const user = await prisma.user.create({ data: input });
return UserSchema.parse(user);
}),
getById: publicProcedure
.input(z.object({ id: z.string() }))
.query(async ({ input }) => {
const user = await prisma.user.findUnique({ where: { id: input.id } });
return user ? UserSchema.parse(user) : null;
}),
});
Verification
After setup, verify everything works:
// test-setup.ts
import { UserSchema, RoleSchema } from './generated';
import { createRegistry } from 'zodipus/queryEngine';
import { models, modelRelations } from './generated/generated-index';
// Test schema parsing
const user = UserSchema.parse({
id: 'test-id',
email: '[email protected]',
name: null,
role: 'USER',
createdAt: new Date(),
updatedAt: new Date(),
});
console.log('Schema validation:', user);
// Test Query Engine
const registry = createRegistry({ models, relations: modelRelations });
const userQuery = registry.createQuery('user');
console.log('Query Engine:', userQuery({ select: { id: true } }).query);
Troubleshooting Setup
"Cannot find module './generated'"
Run npx prisma generate after adding the generator.
TypeScript errors after generation
Ensure your tsconfig includes the output directory:
{
"include": ["src/**/*", "generated/**/*"]
}
ESM/CJS conflicts
Zodipus outputs CommonJS. If using ESM, ensure your bundler handles the conversion.
For detailed options, see references/GENERATOR-OPTIONS.md.