SyntaxSnap

Prisma to Zod Converter

Keep your database models and frontend validation perfectly in sync. Paste your schema.prisma to generate production-ready Zod schemas with CreateInput types.

Zod Schema
import { z } from 'zod';

// ─── Enums ───────────────────────────────────────────────────────

export const RoleSchema = z.enum(['USER', 'ADMIN', 'MODERATOR']);
export type Role = z.infer<typeof RoleSchema>;

// ─── Models ──────────────────────────────────────────────────────

export const UserSchema = z.object({
  id: z.string(), // @id
  email: z.string(), // @unique
  name: z.string().nullable(),
  bio: z.string().nullable(), // @db.Text
  age: z.number().int().nullable(),
  role: RoleSchema.default('USER'),
  posts: z.array(z.lazy(() => PostSchema)), // relation
  profile: z.lazy(() => ProfileSchema).nullable(), // relation
  createdAt: z.coerce.date(),
  updatedAt: z.coerce.date(), // @updatedAt
});

export type User = z.infer<typeof UserSchema>;

// Input schema — omits auto-generated fields
export const UserCreateInputSchema = UserSchema.omit({ id: true, createdAt: true, updatedAt: true });
export type UserCreateInput = z.infer<typeof UserCreateInputSchema>;

export const ProfileSchema = z.object({
  id: z.string(), // @id
  avatar: z.string(),
  userId: z.string(), // @unique
  user: z.lazy(() => UserSchema), // relation
});

export type Profile = z.infer<typeof ProfileSchema>;

// Input schema — omits auto-generated fields
export const ProfileCreateInputSchema = ProfileSchema.omit({ id: true });
export type ProfileCreateInput = z.infer<typeof ProfileCreateInputSchema>;

export const PostSchema = z.object({
  id: z.number().int(), // @id
  title: z.string(),
  content: z.string().nullable(),
  published: z.boolean().default(false),
  tags: z.array(z.string()),
  metadata: z.record(z.unknown()).nullable(),
  authorId: z.string(),
  author: z.lazy(() => UserSchema), // relation
  createdAt: z.coerce.date(),
});

export type Post = z.infer<typeof PostSchema>;

// Input schema — omits auto-generated fields
export const PostCreateInputSchema = PostSchema.omit({ id: true, createdAt: true });
export type PostCreateInput = z.infer<typeof PostCreateInputSchema>;

Frequently Asked Questions

Does this tool send my Prisma schema to a server?

No. SyntaxSnap converts your schema entirely inside the browser using JavaScript. Your data never leaves your machine — there are no API calls, no telemetry, and no server processing.

Which Prisma field types are supported?

All standard Prisma scalars: String, Int, Float, Decimal, BigInt, Boolean, DateTime, Json, and Bytes. Enums are converted to z.enum(), relations use z.lazy(), and nullable/array modifiers are fully supported.

What is the CreateInput schema in the output?

For each model, the converter generates a CreateInput variant that omits auto-generated fields like @id @default(cuid()), @default(now()), @default(autoincrement()), and @updatedAt. This gives you a ready-to-use schema for validating user input in API routes or Server Actions.

Does it handle Prisma relations and circular references?

Yes. Relation fields are mapped using z.lazy(() => ModelSchema) to support circular and self-referencing models. A depth limit prevents infinite recursion during conversion.

Type Mapping Reference

  • String / String? z.string() / .nullable()
  • Int z.number().int()
  • Float / Decimal z.number()
  • BigInt z.bigint()
  • DateTime z.coerce.date()
  • Json z.record(z.unknown())
  • Bytes z.string()
  • Enum z.enum([...])

Supported Prisma Features

  • All scalar types + BigInt, Bytes, Json
  • Enums with @default()
  • Relations (self-ref, one-to-many, one-to-one)
  • Composite @@id detection
  • @updatedAt auto-omitted from CreateInput
  • ~ @@index, @@unique, @@map (warned, skipped)

Explore More Developer Tools

Boost your productivity with our other privacy-first utilities.

View all Data Conversion tools →

Popular Developer Tools