Randomness
in Code

Seeding Prisma Databases in Next.js

February 12, 2024

While developing applications, it's useful to be able to seed the database for a few reasons: The most obvious being that you have actual data to interact with in the UI, APIs, etc. But even if you were to manually create that data, sometimes the data is tampered with or even ruined while developing features. So having a way to reliably and repeatably seed (and re-seed!) the database becomes as valuable as having good test coverage.

Prisma Seed Scripts

Prisma has recommendations on how to author seed scripts within their docs. The seed script can then be integrated within Prisma's workflow, which will inform Prisma to run the seed script after migrations. This creates a simple workflow, but one you need to be aware of while developing that seed script.

To begin, create a seed script at prisma/seed.ts. The contents should be:

// prisma/seed.ts

async function main() {

  // code to generate items...

}
main()
  .then(async () => {
    await prisma.$disconnect();
  })
  .catch(async (e) => {
    console.error(e);
    await prisma.$disconnect();
    process.exit(1);
  });

Then, in the package.json file, add the following to the prisma section (which you may need to create):

// package.json

{
  ...

  "prisma": {
    "seed": "ts-node -r tsconfig-paths/register --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts"
  },

  ...
}

Note the -r tsconfig-paths/register in the command. This is optional, but will include the paths setup in the tsconfig.json file. This is helpful to allow non-relative imports, sometimes seen as "@/...". See the documentation on tsconfig-paths for more info.

With this in place, you can run the seed script by executing the following command:

$ prisma db seed

One thing to note: Prisma will automatically run the seed script after running initial migrations. Which can be helpful for those just getting started!

Resetting the Database

If you'd like to start over, Prisma also provides the ability to reset the database. This will delete all data and remove the tables, re-run the migrations, and then re-seed the database. To do so, run the following command:

$ prisma migrate reset

If you need to include some environment variables from .env.local (or somewhere else), you can add scripts to the package.json file to easily run these commands:

// package.json

{
  ...

  "scripts": {
    ...

    "db:seed": "dotenv -e .env.local -- prisma db seed",
    "db:reset": "dotenv -e .env.local -- prisma migrate reset",

    ...
  },

  ...
}

Generating Fake Data

You can choose to generate seed data in any way you see fit. But often times coming up with random names and values can be difficult. Faker to the rescue! The API provides many commands to easily generate most anything: https://next.fakerjs.dev/api/.

Images can also be cumbersome to generate. Fortunately, placeholder sites exist to provide fake images. Picsum photos is still around (RIP fillmurray) to supply images at various sizes: https://picsum.photos/.

Combining these tools gives you the ability to write:

// prisma/seed.ts

...

await prisma.foo.create({
  data: {
    name: faker.company.name(),
    date: faker.date.past(),
    imageUrl: 'https://picsum.photos/200/300',
  },
});

...