🚀 Use LAUNCH75 Promo Code At Checkout for 75% Off. Limited Time. Expires in 3 days, 19 hours, 47 minutes, 4 seconds.

Next.js, Drizzle ORM, PostgreSQL and Vercel Tutorial

Learn how to integrate Drizzle ORM with Next.js, PostgreSQL and Vercel.

Step 1: Create a Next.js app

npx create-next-app@latest

Step 2: Cleanup


export default function Home() {
  return <div>Home</div>;


@tailwind base;
@tailwind components;
@tailwind utilities;

Step 3: Deploy to Vercel

npx vercel

Step 4: Create a Postgres Database In Vercel

  • Go to Vercel Dashboard
  • Go to project
  • Go to storage
  • Create a postgres database

In local terminal, run:

vercel env pull .env.local

Step 5: Install @vercel/postgres, Drizzle, and Drizzle Kit

npm i drizzle-orm
npm i @vercel/postgres
npm i -D drizzle-kit

Step 6: Create Drizzle Config


import "@/lib/config";
import { defineConfig } from "drizzle-kit";

export default defineConfig({
  schema: "./lib/schema.ts",
  out: "./drizzle",
  driver: "pg",
  dbCredentials: {
    connectionString: process.env.POSTGRES_URL! + "?sslmode=require",
  verbose: true,
  strict: true,

Step 7: Create the Schema


import {
} from "drizzle-orm/pg-core";

export const users = pgTable(
    id: serial("id").primaryKey(),
    name: text("name").notNull(),
    email: text("email").notNull(),
    image: text("image").notNull(),
    createdAt: timestamp("createdAt").defaultNow().notNull(),
  (users) => {
    return {
      uniqueIdx: uniqueIndex("unique_idx").on(users.email),

Step 8: Create configuration file for loading environment variables


import { loadEnvConfig } from "@next/env";

const projectDir = process.cwd();

Step 9: Create DB connection and helpers


import "@/lib/config";
import { drizzle } from "drizzle-orm/vercel-postgres";
import { sql } from "@vercel/postgres";
import { users } from "./schema";
import * as schema from "./schema";

export const db = drizzle(sql, { schema });

export const getUsers = async () => {
  const selectResult = await db.select().from(users);
  console.log("Results", selectResult);
  return selectResult;

export type NewUser = typeof users.$inferInsert;

export const insertUser = async (user: NewUser) => {
  return db.insert(users).values(user).returning();

export const getUsers2 = async () => {
  const result = await db.query.users.findMany();
  return result;

Step 10: Generate the sql migration file

npx drizzle-kit generate:pg

You may see an error like this:

Transforming const to the configured target environment ("es5") is not supported yet

The work around is to change the target from es5 to es6 in tsconfig.json.

  "compilerOptions": {
    "target": "es6"

After running the generate command, you should see a drizzle folder created.

Step 11: Create the migrate script


import { migrate } from "drizzle-orm/vercel-postgres/migrator";
import { db } from "@/lib/db";

async function main() {
  await migrate(db, { migrationsFolder: "./drizzle" });


Step 12: Run the migrate script

npx tsx scripts/migrate.ts

You should see some files generated in the drizzle folder.

Step 13: Create and run a seed script


import { NewUser, insertUser } from "@/lib/db";

async function main() {
  const newUser: NewUser = {
    email: "foo@example.com",
    image: "some image url",
    name: "foo",
  const res = await insertUser(newUser);
  console.log("insert user success", res);


Run the seed script.

npx tsx scripts/seed.ts

Step 14: Update Home Page to display data

import { getUsers, getUsers2 } from "@/lib/db";

export default async function Home() {
  const data = await getUsers();
  const data2 = await getUsers2();

  return (
      <div>sql-like: {JSON.stringify(data)}</div>
      <div>relational: {JSON.stringify(data2)}</div>

Step 15: Update the schema

Add a field to the users schema in /lib/schema.ts. For example: password: text("password"),

Step 16: Try the push command

The push command syncs the drizzle schema definition schema.ts with the database.

The push command is useful for rapid prototyping.

The generate + migrate commands are useful if you want to keep track of database migrations.

npx drizzle-kit push:pg

Step 17: Add commands to package.json

Add the commands to package.json for future use.

  "scripts": {
    "generate": "drizzle-kit generate:pg",
    "migrate": "npx tsx scripts/migrate.ts",
    "seed": "npx tsx scripts/seed.ts",
    "push": "drizzle-kit push:pg"


Drizzle has two main ways to update database schema:

  1. Generate and migrate - for projects that require migration files.
  2. Push - for prototyping or if project doesn't require migration files.

Drizzle has two main ways to query data:

  1. SQL-like - for SQL-like query builder.
  2. Relational - for ORM-like syntax for fetching data that always outputs 1 SQL query.