Tutorial

Prisma seed data without writing a seed script

The default Prisma answer is a hand-written prisma/seed.ts full of create() calls that you maintain forever. Here is how to get a populated, foreign-key-consistent database straight from your schema.prisma instead, with no script to rot.

SeedBase · ~6 min read

Prisma nails the schema and the client. Data is the part it leaves to you. The official answer is prisma db seed, and all that command does is run a TypeScript file you write and keep up to date by hand. That file is where the pain lives.

The default: a seed.ts you maintain by hand

You wire it up in package.json and write the script:

// package.json
"prisma": { "seed": "tsx prisma/seed.ts" }

// prisma/seed.ts
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();

async function main() {
  const user = await prisma.user.create({
    data: { email: "ada@example.com", name: "Ada" },
  });
  const post = await prisma.post.create({
    data: { title: "Hello", authorId: user.id },
  });
  await prisma.comment.create({
    data: { body: "Nice", postId: post.id, authorId: user.id },
  });
}
main().finally(() => prisma.$disconnect());

For three rows this is fine. For a realistic database it turns into a second codebase, and it has three failure modes that never go away:

The Snaplet gap

The popular escape hatch was Snaplet: it read your schema and generated seed data, so you did not write the script. In 2025 Snaplet shut down its data product, which left a lot of Prisma teams on an abandoned dependency and back to hand-writing seed.ts. The need did not go away, the tool did. (We wrote up the migration angle in SeedBase vs Snaplet Seed.)

What you actually want

The seed data should fall out of the schema you already wrote. Hand a tool your schema.prisma and get back a database where every relation resolves, inserts come out parent-first, and the shape looks like real life, without you describing any of it row by row. That is what SeedBase does.

1. Point it at your schema

SeedBase reads schema.prisma directly, models, fields, enums and @relation directives included:

model User {
  id       Int       @id @default(autoincrement())
  email    String    @unique
  name     String
  posts    Post[]
  comments Comment[]
}
model Post {
  id       Int       @id @default(autoincrement())
  title    String
  author   User      @relation(fields: [authorId], references: [id])
  authorId Int
  comments Comment[]
}
model Comment {
  id       Int    @id @default(autoincrement())
  body     String
  post     Post   @relation(fields: [postId], references: [id])
  postId   Int
  author   User   @relation(fields: [authorId], references: [id])
  authorId Int
}

2. Generate and pull the data

Create a project from the schema, generate, and pull the result as SQL (or CSV / JSON). Every authorId and postId points at a row that was actually generated, users come out before posts, posts before comments, so it loads with constraints enabled:

# load the generated seed straight into your database
psql "$DATABASE_URL" -f seedbase-<id>.sql

From the VS Code or JetBrains plugin it is one step: the connection string is auto-detected from your schema.prisma datasource block, and Load into Database (or Reset & Reseed) runs it for you without leaving the editor.

3. Keep prisma db seed if you like it

You do not have to drop the command. Point its script at the generated SQL instead of a hand-maintained seed.ts, and prisma db seed keeps working, it just stops being a file you edit by hand every time the schema changes.

Determinism: generation is seeded, so the same seed reproduces the same rows. Your CI pipeline gets a stable dataset on every run, not a fresh random one, which makes failing tests reproducible.
Honest scope. If your seed is genuinely three fixed rows for one test, a tiny seed.ts is fine, keep it. This earns its place when your schema is relational and you want a realistic, populated database without babysitting a script. SeedBase was tested against a real 20-app project with 226 tables, which is where the relation ordering and distribution handling came from. EU-hosted, no third-party trackers, export everything, so you are never locked in the way the Snaplet shutdown taught everyone to fear.

FAQ

Do I still need a prisma/seed.ts file?

No. You stop hand-writing create() calls. Generate a dataset from your schema, pull it as SQL and load it, or load it straight into your database from the editor plugin. If you like the prisma db seed command, point its script at the generated SQL instead of a hand-maintained seed.ts.

Does SeedBase read my schema.prisma directly?

Yes. It parses schema.prisma, the models, fields, enums and @relation directives, and generates a referentially consistent dataset where parent rows are inserted before the children that reference them, so it loads with foreign key constraints enabled.

Is this a Snaplet seed replacement?

It fills the same gap: generate seed data from your schema instead of writing and maintaining a script. Snaplet shut down its data product in 2025. SeedBase is maintained and EU-hosted, and you can export everything, so there is no lock-in. More in SeedBase vs Snaplet Seed.

Is the seed data deterministic for CI?

Yes. Generation is seeded, so the same seed reproduces the same rows, and a CI pipeline gets a stable, reproducible dataset on every run.

Seed Prisma from your schema, not a script

Point SeedBase at your schema.prisma and generate a populated, relation-consistent database with realistic distributions. Free tier, no credit card.

  • Reads schema.prisma
  • Every relation resolves
  • SQL / CSV / JSON
  • EU-hosted
Generate Prisma seed data, free

More: Prisma test data · vs Snaplet Seed · why Faker breaks on FKs