@nuxt-drizzle/module
v0.0.42
Published
Nuxt module for automating Drizzle ORM setup with conditional database driver imports to prevent unused dependencies in the final bundle.
Readme
Nuxt Drizzle
⚠️ Under Heavy Development - API may change until v1 release
Nuxt module for automating Drizzle ORM setup with support for multiple datasources and conditional database driver imports.
Try it Online
Open the playground in Stackblitz to try Nuxt Drizzle without any local setup.
Features
- 🚅 Multiple Datasources - Support for multiple named database connections
- 📦 Conditional imports - Avoid bundling unused database drivers
- 🔧 Seamless Nuxt integration - Auto-discovers Drizzle configs in subdirectories
- 🛠️ Migration support - Built-in migration handling with hooks
- ✅ Multi-database support - SQLite, PostgreSQL, MySQL, Pglite and Cloudflare D1 (via binding or HTTP API)
- 🪝 Nitro hooks - Lifecycle hooks for migrations and seeding
Quick Setup
- Install the module:
# Add Nuxt module
pnpx nuxt module add @nuxt-drizzle/module- Install the database driver(s) you need:
# For SQLite
pnpm add drizzle-orm better-sqlite3
# For PostgreSQL
pnpm add drizzle-orm postgres
# For MySQL
pnpm add drizzle-orm mysql2
# For Pglite
pnpm add drizzle-orm @electric-sql/pglite- Configure your database connections in
nuxt.config.ts:
export default defineNuxtConfig({
modules: ['@nuxt-drizzle/module'],
nitro: {
experimental: {
database: true,
},
database: {
users: {
connector: 'sqlite',
url: 'file::memory:',
},
content: {
connector: 'pglite',
database: 'content',
},
},
},
// Optional: customize where to search for drizzle configs
drizzle: {
baseDir: '~~/server/drizzle',
},
})- Create Drizzle config files for each datasource in subdirectories:
// server/drizzle/users/drizzle.config.ts
import { defineConfig } from '@nuxt-drizzle/module/config'
export default defineConfig({
dialect: 'sqlite', // or 'postgresql', 'mysql'
schema: './schema.ts',
out: './migrations',
strict: true,
}, __dirname)Directory Structure
Each datasource can have multiple dialect configurations. Here's an example with multi-driver support:
server/
└── drizzle/
├── users/
│ ├── drizzle.config.ts # Main config (optional)
│ ├── drizzle-sqlite.config.ts # SQLite config
│ ├── drizzle-pglite.config.ts # Pglite config
│ ├── sqlite/
│ │ ├── schema.ts
│ │ └── migrations/
│ └── pglite/
│ ├── schema.ts
│ └── migrations/
└── content/
├── drizzle-sqlite.config.ts
├── drizzle-mysql.config.ts
├── drizzle-pglite.config.ts
├── sqlite/
│ ├── schema.ts
│ └── migrations/
├── mysql/
│ ├── schema.ts
│ └── migrations/
└── pglite/
├── schema.ts
└── migrations/Each dialect subdirectory contains its own schema and migrations, allowing you to use different databases for different datasources.
Usage
Accessing a Datasource
Use useDrizzle(event, name) to access a specific datasource:
// server/api/users.get.ts
export default defineEventHandler(async (event) => {
const { db, schema } = useDrizzle(event, 'users')
return await db.select().from(schema.users)
})Defining Schema
// server/drizzle/users/schema.ts
import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core'
export const users = sqliteTable('users', {
id: text('id').primaryKey(),
name: text('name').notNull(),
email: text('email').notNull(),
})Migrations
The module provides a useDrizzleMigrations(name) helper for running migrations:
// server/plugins/migrate.ts
import type { DrizzleDatasources } from '#nuxt-drizzle/virtual/datasources'
export default defineNitroPlugin((nitro) => {
nitro.hooks.hookOnce('drizzle:created', async (datasources: DrizzleDatasources) => {
for (const [name, datasource] of Object.entries(datasources)) {
const migrations = await useDrizzleMigrations(name as keyof DrizzleDatasources)
if (!migrations) continue
for await (const { id, query } of migrations) {
await datasource.db.run(query)
}
}
nitro.hooks.callHook('drizzle:migrated', datasources)
})
})Seeding Data
Use the drizzle:migrated hook to seed data:
// server/plugins/seed.ts
export default defineNitroPlugin((nitro) => {
nitro.hooks.hookOnce('drizzle:migrated', async (datasources) => {
await datasources.users.db.insert(datasources.users.schema.users).values([
{ id: 1, name: 'John Doe', email: '[email protected]' },
])
})
})Helper Functions
The module provides dialect-specific helper functions for handling conflicts during inserts. These helpers are accessed via useDrizzleHelpers(name):
// server/plugins/seed.ts
export default defineNitroPlugin((nitro) => {
nitro.hooks.hookOnce('drizzle:migrated', async (datasources) => {
const { onConflictDoNothing } = useDrizzleHelpers('users')
await onConflictDoNothing(
useDrizzlePrimaryKey(schema.users),
db.insert(schema.users).values([
{ id: 1, name: 'John Doe', email: '[email protected]' },
]),
)
})
})Available helpers by dialect:
| Dialect | Helpers |
|---------|---------|
| SQLite | onConflictDoUpdate, onConflictDoNothing |
| PostgreSQL | onConflictDoUpdate, onConflictDoNothing |
| MySQL | onConflictDoUpdate, onConflictDoNothing |
Functions:
onConflictDoNothing(target, insert)- Returns the insert statement with ON CONFLICT DO NOTHINGonConflictDoUpdate(target, insert, options)- Returns the insert statement with ON CONFLICT DO UPDATE SETuseDrizzleHelpers(name)- Gets the helper functions for a datasourceuseDrizzlePrimaryKey(table)- Gets the primary key columns from a table schema
Configuration Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| baseDir | string | ./server/drizzle | Directory to search for Drizzle configs |
| configPattern | string \| string[] | ['*/drizzle.config.*', '*/drizzle-*.config.*'] | Glob patterns for Drizzle config files |
| migrations | boolean | true | Enable migrations composable and storage |
Datasource Naming
Datasource names are derived from the directory containing the drizzle.config.ts file:
server/drizzle/users/drizzle.config.ts→ datasource namedusersserver/drizzle/content/drizzle.config.ts→ datasource namedcontent
Supported Databases
| Database | Dialect | Driver | Package |
|----------|---------|--------|---------|
| SQLite | sqlite | better-sqlite3 | better-sqlite3 |
| PostgreSQL | postgresql | postgres | postgres |
| MySQL | mysql | mysql2 | mysql2 |
| Pglite | postgresql | pglite | @electric-sql/pglite |
| Nitro Database | db0 | - | db0 |
Nitro Database Integration
The module integrates with Nitro's experimental database feature:
export default defineNuxtConfig({
nitro: {
experimental: {
database: true,
},
database: {
users: {
connector: 'sqlite'
},
},
},
})API Reference
useDrizzle(event, name)
Returns the database instance and schema for a named datasource.
const { db, schema } = useDrizzle(event, 'users')useDrizzleHelpers(name)
Returns helper functions for a named datasource.
const { onConflictDoNothing, onConflictDoUpdate } = useDrizzleHelpers('users')useDrizzlePrimaryKey(table)
Returns the primary key columns from a table schema.
const primaryKey = useDrizzlePrimaryKey(schema.users)useDrizzleMigrations(name)
Returns an async iterator of migration files for a datasource.
const migrations = await useDrizzleMigrations('users')Nitro Hooks
drizzle:created- Called when datasources are created, receivesDrizzleDatasourcesdrizzle:migrated- Called after migrations complete, receivesDrizzleDatasources
Nuxt Hooks
nuxt-drizzle:datasources- Called with array of datasource info
# Install dependencies
pnpm install
# Generate type stubs
pnpm run dev:prepare
# Develop with the playground
pnpm run dev
# Build the playground
pnpm run dev:build
# Run ESLint
pnpm run lint
# Run Vitest
pnpm run test
pnpm run test:watch
# Release new version
pnpm run release