Drizzle with Vercel Edge Functions
This tutorial demonstrates how to use Drizzle ORM with Vercel Functions in Edge runtime.
- You should have the latest version of Vercel CLI installed.
npm i -g vercel
yarn add -g vercel
pnpm add -g vercel
bun add -g vercel
- You should have an existing Next.js project or create a new one using the following command:
npx create-next-app@latest --typescript
- You should have installed Drizzle ORM and Drizzle kit. You can do this by running the following command:
npm i drizzle-orm
npm i -D drizzle-kit
yarn add drizzle-orm
yarn add -D drizzle-kit
pnpm add drizzle-orm
pnpm add -D drizzle-kit
bun add drizzle-orm
bun add -D drizzle-kit
Edge-compatible driver
When using Drizzle ORM with Vercel Edge functions you have to use edge-compatible drivers because the functions run in Edge runtime not in Node.js runtime, so there are some limitations of standard Node.js APIs.
You can choose one of these drivers according to your database dialect:
- Neon serverless driver allows you to query your Neon Postgres databases from serverless and edge environments over HTTP or WebSockets in place of TCP. We recommend using this driver for connecting to
Neon Postgres
. - Vercel Postgres driver is built on top of the
Neon serverless driver
. We recommend using this driver for connecting toVercel Postgres
. - PlanetScale serverless driver allows you access any
MySQL
client and execute queries over an HTTP connection, which is generally not blocked by cloud providers. - libSQL client allows you to access Turso database.
Navigation
- Navigate directly to the PostgreSQL client section.
- Navigate directly to the Vercel Postgres client section.
- Navigate directly to the MySQL client section.
- Navigate directly to the Turso section.
Any PostgreSQL client
Setup Drizzle config file
Drizzle config - a configuration file that is used by Drizzle Kit and contains all the information about your database connection, migration folder and schema files.
Create a drizzle.config.ts
file in the root of your project and add the following content:
import { Config } from "drizzle-kit";
export default defineConfig({
schema: "./app/db/schema.ts",
dialect: "postgresql",
dbCredentials: {
url: process.env.POSTGRES_URL!,
},
});
Configure your database connection string in the .env
file:
POSTGRES_URL="postgres://[user]:[password]@[host]-[region].aws.neon.tech:5432/[db-name]?sslmode=[ssl-mode]"
Create a table
Create a schema.ts
file in the app/db
directory and declare a table schema:
import { pgTable, serial, text } from "drizzle-orm/pg-core";
export const usersTable = pgTable('users_table', {
id: serial('id').primaryKey(),
name: text('name').notNull(),
age: text('age').notNull(),
email: text('email').notNull().unique(),
})
Push your changes to the database
Run the drizzle-kit push
command to push your changes to the database:
npx drizzle-kit push
Learn more about push command here. Alternatively, apply your changes through the migration process.
Connect Drizzle ORM to your database
Install the @neondatabase/serverless
driver:
npm i @neondatabase/serverless
yarn add @neondatabase/serverless
pnpm add @neondatabase/serverless
bun add @neondatabase/serverless
Create a db.ts
file in the app/db
directory and set up your database configuration:
import { Pool } from '@neondatabase/serverless';
import { drizzle } from 'drizzle-orm/neon-serverless';
const pool = new Pool({ connectionString: process.env.POSTGRES_URL! });
export const db = drizzle(pool)
Create an API route
Create /api/hello/route.ts
in app
directory. To learn more about how to write a function, see the Functions API Reference and Vercel Functions Quickstart.
import { db } from "@/app/db/db";
import { usersTable } from "@/app/db/schema";
import { NextResponse } from "next/server";
export const dynamic = 'force-dynamic'; // static by default, unless reading the request
export const runtime = 'edge' // specify the runtime to be edge
export async function GET(request: Request) {
const users = await db.select().from(usersTable)
return NextResponse.json({ users, message: 'success' });
}
Test your code locally
Run the next dev
command to start your local development server:
npx next dev
Navigate to the route you created (e.g. /api/hello)
in your browser:
{
"users": [],
"message": "success"
}
Deploy your project
Create a new project in the dashboard or run the vercel
command to deploy your project:
vercel
Add POSTGRES_URL
environment variable:
vercel env add POSTGRES_URL
Redeploy your project to update your environment variables:
vercel
Finally, you can use URL of the deployed project and navigate to the route you created (e.g. /api/hello)
to access your edge function.
Vercel Postgres client
You can check quickstart guide for Drizzle with Vercel Postgres client in the documentation.
Setup Drizzle config file
Drizzle config - a configuration file that is used by Drizzle Kit and contains all the information about your database connection, migration folder and schema files.
Create a drizzle.config.ts
file in the root of your project and add the following content:
import { defineConfig } from "drizzle-kit";
export default defineConfig({
schema: "./app/db/schema.ts",
dialect: "postgresql",
dbCredentials: {
url: process.env.POSTGRES_URL!,
},
});
Configure your database connection string in the .env
file:
POSTGRES_URL="postgres://[user]:[password]@[host]-[region].aws.neon.tech:5432/[db-name]?sslmode=[ssl-mode]"
Create a table
Create a schema.ts
file in the app/db
directory and declare a table schema:
import { pgTable, serial, text } from "drizzle-orm/pg-core";
export const usersTable = pgTable('users_table', {
id: serial('id').primaryKey(),
name: text('name').notNull(),
age: text('age').notNull(),
email: text('email').notNull().unique(),
})
Push your changes to the database
Run the drizzle-kit push
command to push your changes to the database:
npx drizzle-kit push
Learn more about push command here. Alternatively, apply your changes through the migration process.
Connect Drizzle ORM to your database
Install the @vercel/postgres
driver:
npm i @vercel/postgres
yarn add @vercel/postgres
pnpm add @vercel/postgres
bun add @vercel/postgres
Create a db.ts
file in the app/db
directory and set up your database configuration:
import { sql } from '@vercel/postgres';
import { drizzle } from 'drizzle-orm/vercel-postgres';
export const db = drizzle(sql)
Create an API route
Create /api/hello/route.ts
in app
directory. To learn more about how to write a function, see the Functions API Reference and Vercel Functions Quickstart.
import { db } from "@/app/db/db";
import { usersTable } from "@/app/db/schema";
import { NextResponse } from "next/server";
export const dynamic = 'force-dynamic'; // static by default, unless reading the request
export const runtime = 'edge' // specify the runtime to be edge
export async function GET(request: Request) {
const users = await db.select().from(usersTable)
return NextResponse.json({ users, message: 'success' });
}
Test your code locally
Run the next dev
command to start your local development server:
npx next dev
Navigate to the route you created (e.g. /api/hello)
in your browser:
{
"users": [],
"message": "success"
}
Deploy your project
Create a new project in the dashboard or run the vercel
command to deploy your project:
vercel
Add POSTGRES_URL
environment variable:
vercel env add POSTGRES_URL
Redeploy your project to update your environment variables:
vercel
Finally, you can use URL of the deployed project and navigate to the route you created (e.g. /api/hello)
to access your edge function.
Any MySQL client
In this tutorial we use PlanetScale MySQL.
Setup Drizzle config file
Drizzle config - a configuration file that is used by Drizzle Kit and contains all the information about your database connection, migration folder and schema files.
Create a drizzle.config.ts
file in the root of your project and add the following content:
import { defineConfig } from "drizzle-kit";
export default defineConfig({
schema: "./app/db/schema.ts",
dialect: "mysql",
dbCredentials: {
url: process.env.MYSQL_URL!,
},
});
Configure your database connection string in the .env
file:
MYSQL_URL="mysql://[user]:[password]@[host].[region].psdb.cloud/[db-name]?ssl={'rejectUnauthorized':[ssl-rejectUnauthorized]}"
Create a table
Create a schema.ts
file in the app/db
directory and declare a table schema:
import { mysqlTable, serial, text } from "drizzle-orm/mysql-core";
export const usersTable = mysqlTable('users_table', {
id: serial('id').primaryKey(),
name: text('name').notNull(),
age: text('age').notNull(),
email: text('email').notNull().unique(),
})
Push your changes to the database
Run the drizzle-kit push
command to push your changes to the database:
npx drizzle-kit push
Learn more about push command here. Alternatively, apply your changes through the migration process.
Connect Drizzle ORM to your database
Install the @planetscale/database
driver:
npm i @planetscale/database
yarn add @planetscale/database
pnpm add @planetscale/database
bun add @planetscale/database
Create a db.ts
file in the app/db
directory and set up your database configuration:
import { drizzle } from "drizzle-orm/planetscale-serverless";
import { Client } from "@planetscale/database";
const client = new Client({
url: process.env.MYSQL_URL!,
})
export const db = drizzle(client)
Create an API route
Create /api/hello/route.ts
in app
directory. To learn more about how to write a function, see the Functions API Reference and Vercel Functions Quickstart.
import { db } from "@/app/db/db";
import { usersTable } from "@/app/db/schema";
import { NextResponse } from "next/server";
export const dynamic = 'force-dynamic'; // static by default, unless reading the request
export const runtime = 'edge' // specify the runtime to be edge
export async function GET(request: Request) {
const users = await db.select().from(usersTable)
return NextResponse.json({ users, message: 'success' });
}
Test your code locally
Run the next dev
command to start your local development server:
npx next dev
Navigate to the route you created (e.g. /api/hello)
in your browser:
{
"users": [],
"message": "success"
}
Deploy your project
Create a new project in the dashboard or run the vercel
command to deploy your project:
vercel
Add MYSQL_URL
environment variable:
vercel env add MYSQL_URL
Redeploy your project to update your environment variables:
vercel
Finally, you can use URL of the deployed project and navigate to the route you created (e.g. /api/hello)
to access your edge function.
Turso
You can check quickstart guide or tutorial for Drizzle with Turso in the documentation.
Setup Drizzle config file
Drizzle config - a configuration file that is used by Drizzle Kit and contains all the information about your database connection, migration folder and schema files.
Create a drizzle.config.ts
file in the root of your project and add the following content:
import { defineConfig } from "drizzle-kit";
export default defineConfig({
schema: "./app/db/schema.ts",
dialect: "sqlite",
driver: "turso",
dbCredentials: {
url: process.env.TURSO_CONNECTION_URL!,
authToken: process.env.TURSO_AUTH_TOKEN!,
},
});
Configure your database connection string in the .env
file:
TURSO_CONNECTION_URL="libsql://[db-name].turso.io"
TURSO_AUTH_TOKEN="[auth-token]"
Create a table
Create a schema.ts
file in the app/db
directory and declare a table schema:
import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
export const usersTable = sqliteTable('users_table', {
id: integer('id').primaryKey(),
name: text('name').notNull(),
age: text('age').notNull(),
email: text('email').notNull().unique(),
})
Push your changes to the database
Install the @libsql/client
driver:
npm i @libsql/client
yarn add @libsql/client
pnpm add @libsql/client
bun add @libsql/client
Run the drizzle-kit push
command to push your changes to the database:
npx drizzle-kit push
Learn more about push command here. Alternatively, apply your changes through the migration process.
Connect Drizzle ORM to your database
Create a db.ts
file in the app/db
directory and set up your database configuration:
import { drizzle } from 'drizzle-orm/libsql';
import { createClient } from '@libsql/client';
const client = createClient({
url: process.env.TURSO_CONNECTION_URL!,
authToken: process.env.TURSO_AUTH_TOKEN!,
});
export const db = drizzle(client)
Create an API route
Create /api/hello/route.ts
in app
directory. To learn more about how to write a function, see the Functions API Reference and Vercel Functions Quickstart.
import { db } from "@/app/db/db";
import { usersTable } from "@/app/db/schema";
import { NextResponse } from "next/server";
export const dynamic = 'force-dynamic'; // static by default, unless reading the request
export const runtime = 'edge' // specify the runtime to be edge
export async function GET(request: Request) {
const users = await db.select().from(usersTable)
return NextResponse.json({ users, message: 'success' });
}
Test your code locally
Run the next dev
command to start your local development server:
npx next dev
Navigate to the route you created (e.g. /api/hello)
in your browser:
{
"users": [],
"message": "success"
}
Deploy your project
Create a new project in the dashboard or run the vercel
command to deploy your project:
vercel
Add TURSO_CONNECTION_URL
and TURSO_AUTH_TOKEN
environment variables:
vercel env add TURSO_CONNECTION_URL
vercel env add TURSO_AUTH_TOKEN
Redeploy your project to update your environment variables:
vercel
Finally, you can use URL of the deployed project and navigate to the route you created (e.g. /api/hello)
to access your edge function.