Blazing Fast Next.js with Drizzle ORM and Turso Database

Build lightning-fast Next.js apps with ease using Drizzle ORM and Turso database. This step-by-step guide shows you how to connect, query, and deploy a performant full-stack app.

June 30, 2024 (5mo ago)| 📖 6 min read

Blazing Fast Next.js with Drizzle ORM and Turso Database

Want to build performant, scalable, and type-safe Next.js applications with a production ready database? Look no further than the powerful combination of Drizzle ORM and Turso , SQLite for Production.

Introduction

Drizzle ORM is a type-safe and performant ORM for TypeScript and JavaScript. It offers a clean and intuitive API for interacting with your database, making it easier to write and maintain your application's data logic. Turso, on the other hand, is a serverless database platform that provides a scalable and cost-effective solution for deploying your applications.

Why Choose This Stack?

  • Next.js: The go-to framework for building modern web applications, offering server-side rendering, automatic code splitting, and a robust routing system. Learn more about Next.js
  • Drizzle ORM: A type-safe and performant ORM for TypeScript and JavaScript, simplifying database interactions and ensuring code clarity. Explore Drizzle ORM
  • Turso: A serverless database platform that provides a scalable and cost-effective solution for deploying your applications. Turso's edge SQLite database offers lightning-fast performance and seamless integration with Next.js. Discover Turso
  • Bun: A fast, all-in-one JavaScript runtime that offers a powerful alternative to Node.js. Learn more about Bun

Setup

Let's get started with setting up Drizzle ORM with Turso in your Next.js application.

1. Create a Next.js Project

If you don't have an existing Next.js project, create one using the following command:

bunx create-next-app@latest my-drizzle-turso-app

Replace my-drizzle-turso-app with your desired project name.

2. Install Dependencies

Install the necessary dependencies for Drizzle ORM, Turso, and SQLite:

bun add drizzle-orm @libsql/client dotenv bun add -D drizzle-kit

3. Spin Up Your Turso Database

Sign up or Log in: Head over to Turso and create a free account or log in if you already have one.

Signup or Login to Turso CLI

Signup:

turso auth signup

Login:

turso auth login

Create a New Database

Create a new database using the following command:

turso db create drizzle-turso-db

Get turso credentials

Database URL:

turso db show --url drizzle-turso-db

Authentication token:

turso db tokens create drizzle-turso-db

4. Setup Environment Variables

Update your .env file with the connection URL and authentication token:

.env
TURSO_DATABASE_URL= TURSO_AUTH_TOKEN=

5. Connect Drizzle ORM to Your Database

Create a file src/db/db.ts and set up your database configuration:

src/db/db.ts
import { drizzle } from 'drizzle-orm/libsql'; import { createClient } from '@libsql/client'; import * as schema from './schema'; if (!process.env.TURSO_DATABASE_URL) { throw new Error('TURSO_DATABASE_URL is not defined'); } if (!process.env.TURSO_AUTH_TOKEN) { throw new Error('TURSO_AUTH_TOKEN is not defined'); } const client = createClient({ url: process.env.TURSO_DATABASE_URL!, authToken: process.env.TURSO_AUTH_TOKEN, }); export const db = drizzle(client, { schema });

6. Define Database Schema

Create a file src/db/schema.ts to define your database schema:

src/db/schema.ts
import { sql } from 'drizzle-orm'; import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core'; export const usersTable = sqliteTable('users', { id: integer('id').primaryKey(), name: text('name').notNull(), age: integer('age').notNull(), email: text('email').unique().notNull(), }); export type InsertUser = typeof usersTable.$inferInsert; export type SelectUser = typeof usersTable.$inferSelect; export const postsTable = sqliteTable('posts', { id: integer('id').primaryKey(), title: text('title').notNull(), content: text('content').notNull(), userId: integer('user_id') .notNull() .references(() => usersTable.id, { onDelete: 'cascade' }), createdAt: text('created_at') .default(sql`(CURRENT_TIMESTAMP)`) .notNull(), updateAt: integer('updated_at', { mode: 'timestamp' }).$onUpdate( () => new Date(), ), }); export type InsertPost = typeof postsTable.$inferInsert; export type SelectPost = typeof postsTable.$inferSelect;

7. Setup Drizzle Configuration

Create a drizzle.config.ts file in the root of your project:

drizzle.config.ts
import type { Config } from 'drizzle-kit'; import dotenv from 'dotenv'; dotenv.config({ path: '.env.local', }); export default { schema: './src/db/schema.ts', driver: 'turso', dialect: 'sqlite', dbCredentials: { url: process.env.TURSO_DATABASE_URL! as string, authToken: process.env.TURSO_AUTH_TOKEN! as string, }, out: './drizzle', verbose: true, strict: true, } satisfies Config;

8. Generate and Apply Migrations

Add this script to your package.json file:

package.json
"db:generate": "drizzle-kit generate", "db:studio": "drizzle-kit studio", "db:migrate": "drizzle-kit migrate"

Generate migrations using Drizzle Kit:

bun run db:generate

Apply the migrations:

bun run db:migrate

Open the Drizzle Studio:

bun run db:studio

Deploy to Vercel

Deploy your Next.js application, ensuring you set the TURSO_DATABASE_URL and TURSO_AUTH_TOKEN environment variables in your deployment settings.

Conclusion

Congratulations! You've successfully integrated Drizzle ORM and Turso into your Next.js application. You can now build feature-rich and performant applications with ease, leveraging the power of type-safe database interactions and a serverless edge database.


Links