For the complete documentation index, see llms.txt. Prefer markdown by appending.mdto documentation URLs or sendingAccept: text/markdown.
Overview
Drizzle ORM for typed SQL, migrations, and queries. How the database layer connects to Better Auth and the Hono API modules.
We're using Drizzle ORM to interact with the database. It basically adds a little layer of abstraction between our code and the database.
If you know SQL, you know Drizzle.
For the database we're leveraging PostgreSQL, but you could use any other database that Drizzle ORM supports (basically any SQL database e.g. MySQL, SQLite, etc.).
Why Drizzle ORM?
Drizzle ORM is a powerful tool that allows you to interact with the database in a type-safe manner. It ships with 0 (!) dependencies and is designed to be fast and easy to use.
Setup
To start interacting with the database you first need to ensure that your database service instance is up and running.
For local development we recommend using the Docker container.
You can start the container with the following command:
pnpm services:setupThis will start all the services (including the database container) and initialize the database with the latest schema.
Where is DATABASE_URL?
DATABASE_URL is a connection string that is used to connect to the database. When the command will finish it will be displayed in the console and setup to your environment variables.
You can also use a cloud instance of database (e.g. Supabase, Neon, Turso, etc.), although it's not recommended for local development.
If you choose Supabase as your provider, follow the Supabase recipe for details on configuring DATABASE_URL and running migrations.
Where is DATABASE_URL?
It's available in your provider's project dashboard. You'll need to copy the connection string from there and add it to your .env.local file. The format will look something like:
- Neon:
postgresql://user:password@ep-xyz-123.region.aws.neon.tech/dbname - Turso:
libsql://your-db-xyz.turso.io
Make sure to keep this URL secure and never commit it to version control.
Then, set the DATABASE_URL environment variable in the root .env.local file. The value should match the Postgres container started by pnpm services:setup (also pre-filled in .env.example):
# The database URL is used to connect to your database.
DATABASE_URL="postgresql://turbostarter:turbostarter@localhost:5432/core"Using local Supabase instead?
If you run Postgres through the Supabase CLI rather than pnpm services:setup, use the DB URL from supabase status instead (often port 54322).
You're ready to go! 🥳
Studio
TurboStarter provides you also with an interactive UI where you can explore your database and test queries called Studio.
To run the Studio, you can use the following command:
pnpm with-env pnpm --filter @workspace/db db:studioThis will start the Studio on https://local.drizzle.studio.

Next steps
- Update schema - learn about schema and how to update it.
- Generate & run migrations - migrate your changes to the database.
- Initialize client - initialize the database client and start interacting with the database.
- Switch to Prisma - replace Drizzle with Prisma ORM if your team prefers a Prisma-first database workflow.
Schema
Design tables and relations in the shared Drizzle schema. Migrations, conventions, and extending the data model for new features.
Migrations
Generate and apply Drizzle migrations with ready-made CLI commands — use db:generate to create SQL files and db:migrate to push them to your database.
Database client
Use database client to interact with the database. How data is modeled, migrated, and accessed from your web app.
SQLite
Switch the project from PostgreSQL to SQLite. Database setup, schema changes, and client usage with Drizzle ORM.
MySQL
Switch from the default PostgreSQL to MySQL: update the Drizzle driver, schema imports, Better Auth adapter, and a handful of PostgreSQL-specific patterns.
How is this guide?
Last updated on