Setup

Configure your SQL database in Nuxt with Drizzle ORM, including installation, environment setup, and database connection initialization.

NuxtHub Database provides a type-safe SQL database powered by Drizzle ORM, supporting PostgreSQL, MySQL, and SQLite with smart detection and automatic migrations at build time.

Getting started

Install dependencies

Install Drizzle ORM, Drizzle Kit, and the appropriate driver(s) for the database you are using:

pnpm add drizzle-orm drizzle-kit postgres @electric-sql/pglite
NuxtHub automatically detects your database connection using environment variables:
  • Uses PGlite (embedded PostgreSQL) if no environment variables are set.
  • Uses postgres-js driver if you set DATABASE_URL, POSTGRES_URL, or POSTGRESQL_URL environment variable.

Set SQL dialect

Enable the database in your nuxt.config.ts by setting the db property to your desired SQL dialect:

nuxt.config.ts
export default defineNuxtConfig({
  hub: {
    db: 'postgresql'
  }
})

Database schema

Create your database schema with full TypeScript support using Drizzle ORM:

server/db/schema.ts
import { pgTable, text, serial, timestamp } from 'drizzle-orm/pg-core'

export const users = pgTable('users', {
  id: serial().primaryKey(),
  name: text().notNull(),
  email: text().notNull().unique(),
  password: text().notNull(),
  avatar: text().notNull(),
  createdAt: timestamp().notNull().defaultNow(),
})
Learn more about defining the database schema files.

Generate migrations

Generate the database migrations from your schema:

Terminal
npx nuxt db generate

This creates SQL migration files in server/db/migrations/{dialect}/ which are automatically applied during deployment and development.

That's it! You can now start your development server and query your database using the db instance from hub:db.
Make sure to run npx nuxt db generate to generate the database migrations each time you change your database schema and restart the development server.

AI Agents

If you work with an IDE that supports AI agents, you can add the following text in your Agents.md or .cursor/rules file:

# Agent Instructions

/** ... your agent instructions ... */

## Database

- **Database Dialect**: The database dialect is set in the `nuxt.config.ts` file, within the `hub.db` option or `hub.db.dialect` property.
- **Drizzle Config**: Don't generate the `drizzle.config.ts` file manually, it is generated automatically by NuxtHub.
- **Generate Migrations**: Use `npx nuxt db generate` to automatically generate database migrations from schema changes
- **Never Write Manual Migrations**: Do not manually create SQL migration files in the `server/db/migrations/` directory
- **Workflow**:
  1. Create or modify the database schema in `server/db/schema.ts` or any other schema file in the `server/db/schema/` directory
  2. Run `npx nuxt db generate` to generate the migration
  3. Run `npx nuxt db migrate` to apply the migration to the database, or run `npx nuxt dev` to apply the migration during development
- **Access the database**: Use the `db` instance from `hub:db` to query the database, it is a Drizzle ORM instance.

Local development

During local development, view and edit your database from Nuxt DevTools using the Drizzle Studio:

At the moment, Drizzle Studio does not support SQLite.

Build-time Hooks

'hub:db:migrations:dirs'
(dirs: string[]) => void | Promise<void>
Add additional directories to scan for database migration files (.sql).
nuxt.config.ts
export default defineNuxtConfig({
  hooks: {
    'hub:db:migrations:dirs': (dirs) => {
      dirs.push('my-module/db/migrations')
    }
  }
})
'hub:db:queries:paths'
(queries: string[], dialect: string) => void | Promise<void>
Add queries that are not tracked in the _hub_migrations table which are applied after the database migrations complete.
nuxt.config.ts
export default defineNuxtConfig({
  hooks: {
    'hub:db:queries:paths': (queries, dialect) => {
      queries.push('my-module/db/queries')
    }
  }
})
'hub:db:schema:extend'
({ paths: string[], dialect: string }) => void | Promise<void>
Extend the database schema with additional files.
modules/my-module/index.ts
import { createResolver, defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  setup(options, nuxt) {
    const { resolve } = createResolver(import.meta.url)

    nuxt.hook('hub:db:schema:extend', ({ paths, dialect }) => {
      paths.push(resolve(`./db/schema/pages.${dialect}.ts`))
    })
  }
})
Learn more about Nuxt server hooks on the Nuxt documentation.

Advanced configuration

For advanced use cases, you can explicitly configure the database connection:

nuxt.config.ts
export default defineNuxtConfig({
  hub: {
    db: {
      dialect: 'postgresql',
      driver: 'postgres-js', // Optional: explicitly choose driver
      connection: {
        connectionString: process.env.DATABASE_URL
      }
    }
  }
})

Cloudflare D1 over HTTP

Use the d1-http driver to access a Cloudflare D1 database over HTTP. This is useful when you want to query your D1 database when hosting on other platforms.

nuxt.config.ts
export default defineNuxtConfig({
  hub: {
    db: {
      dialect: 'sqlite',
      driver: 'd1-http'
    }
  }
})

This driver requires the following environment variables:

VariableDescription
NUXT_HUB_CLOUDFLARE_ACCOUNT_IDYour Cloudflare account ID
NUXT_HUB_CLOUDFLARE_API_TOKENA Cloudflare API token with D1 permissions
NUXT_HUB_CLOUDFLARE_DATABASE_IDThe ID of your D1 database
You can find your Cloudflare account ID and create API tokens in the Cloudflare dashboard. The API token needs D1:Edit permissions.

Migration guide

Breaking changes in NuxtHub v1: If you're upgrading from a previous version that used hubDatabase(), follow this migration guide.

Configuration changes

The database option has been renamed to db and now accepts a SQL dialect instead of a boolean.

nuxt.config.ts
export default defineNuxtConfig({
  hub: {
-    database: true
+    db: 'sqlite'
  }
})

Valid dialects are sqlite, postgresql and mysql.

Directory changes

The database directory has been renamed from server/database/ to server/db/:

- server/database/schema.ts
+ server/db/schema.ts

- server/database/migrations/
+ server/db/migrations/

Make sure to move your schema and migration files to the new location.

API changes

The old hubDatabase() function has been removed. You must now use Drizzle ORM.

Before:

const db = hubDatabase()
const result = await db.prepare('SELECT * FROM users').all()

After:

const result = await db.select().from(tables.users)

Migration files

Your existing SQL migration files continue to work! Just move them to server/db/migrations/.