nitro-drizzle is a powerful module designed to seamlessly integrate the Drizzle ORM with your Nitro applications. It simplifies database management, schema definition, and migrations, allowing you to build robust and scalable backend services with ease.
- Datasource Management: Easily configure and manage multiple Drizzle ORM datasources within your Nitro project.
- Multiple Database Drivers: Support for various database drivers including SQLite (with
better-sqlite3), PostgreSQL (withpglite), MySQL (withmysql2), and Cloudflare D1. - Automatic Migrations: Configure automatic database migrations on application initialization.
- Type-Safe Schemas: Leverage Drizzle ORM's type-safe schemas for a better development experience.
- Nitro Task Integration: Run Drizzle migrations as Nitro tasks.
- Hot Reloading: Seamless integration with Nitro's development server for hot reloading of datasource configurations and schemas.
To get started, install the nitro-drizzle module and its peer dependencies:
npm install nitro-drizzle drizzle-orm drizzle-kit
# Install database drivers based on your needs:
# SQLite:
npm install better-sqlite3
# PostgreSQL (with pglite):
npm install @electric-sql/pglite
# MySQL:
npm install mysql2
# Cloudflare D1: (nitro-drizzle will use the `wrangler d1 bindings` for a local development, for production you can use `@cloudflare/workers-types` and connect directly to the database)
npm install @cloudflare/workers-typesAdd nitro-drizzle to your nitro.config.ts modules:
// nitro.config.ts
import { defineNitroConfig } from "nitropack/config";
export default defineNitroConfig({
modules: ["nitro-drizzle"],
drizzle: {
datasources: {
content: { drivers: ["sqlite", "d1"] },
},
},
});See ModuleOptions in src/module/index.ts for all available options.
Create your Drizzle configuration files and schemas in the baseDir specified in nitro.config.ts (e.g., server/drizzle/content/drizzle-sqlite.config.ts and server/drizzle/content/sqlite/schema.ts).
import { defineConfig } from "nitro-drizzle/config";
export default defineConfig(
{
strict: true,
dialect: "sqlite",
out: "./sqlite/migrations", // Migration output directory
schema: "./sqlite/schema.ts", // Path to your schema files
migrations: {
table: "drizzle_migrations", // Table to track migrations
},
},
import.meta.url, // Pass import.meta.url for compatibility with "drizzle-kit"
);import { sqliteTable, integer, text } from "drizzle-orm/sqlite-core";
export const posts = sqliteTable("posts", {
id: integer("id").primaryKey({ autoIncrement: true }),
title: text("title").notNull(),
description: text("description").notNull(),
image: text("image").notNull(),
date: integer("date", { mode: "timestamp" }).notNull().defaultNow(),
authors: text("authors", { mode: "json" }).$type<number[]>(),
});
export const comments = sqliteTable("comments", {
id: integer("id").primaryKey({ autoIncrement: true }),
postId: integer("post_id").notNull(),
authorId: integer("author_id").notNull(),
content: text("content").notNull(),
createdAt: integer("created_at", { mode: "timestamp" }).notNull(),
});drizzle-kit generate --config server/drizzle/content/drizzle-sqlite.config.tsYou can access your configured datasources in your Nitro API routes using useDatasource.
// server/routes/index.ts
import { defineEventHandler } from "h3";
import { useDatasource } from "nitro-drizzle/runtime";
export default defineEventHandler(async () => {
await event.context.drizzle.waitReady(); // Wait for "drizzle:init" hook finished
const { database, waitReady } = await useDatasource("content"); // Access the 'content' datasource
await waitReady(); // Wait datasource is ready
const posts = await database.select().from(schema.posts).limit(10);
return { posts };
});If you enabled Nitro tasks in nitro.config.ts, you can run migrations via the Nitro CLI:
npx nitro task drizzle:migrateA minimal layout with SQLite database for content and PostgreSQL database for users. Each datasource has its own drizzle config, schema, and migrations folder.
blog-api/
βββ nitro.config.ts
βββ package.json
βββ server/
βββ drizzle/
βββ content/
β βββ drizzle-sqlite.config.ts
β βββ sqlite/
β βββ migrations/*.sql
β βββ schema/*.ts
βββ users/
βββ drizzle-postgresql.config.ts
βββ postgresql/
βββ migrations/*.sql
βββ schema.ts
- Purpose: Retrieves a Drizzle ORM datasource instance by its configured name. Caches the datasource for reuse.
- Parameters:
name: The unique name of the datasource as defined innitro.config.ts.options(optional):autoClose:boolean(default:true) - Whether to automatically close the datasource when the Nitro app closes.
- Returns: A
Promisethat resolves to the Drizzle ORM datasource instance, includingdatabase(the Drizzle client) andschema(your defined schema).
import { useDatasource } from "nitro-drizzle/runtime";
const myDatasource = await useDatasource("myDatasourceName");
const result = await myDatasource.database.select().from(myDatasource.schema.myTable).all();- Purpose: Provides type-safe dialect-specific handlers for a datasource. Automatically resolves the correct handler based on the configured driver.
- Parameters:
name: The unique name of the datasource as defined innitro.config.ts.handlers: An object mapping dialect names to handler functions. Each handler receives the datasource instance.
- Returns: A
Promisethat resolves to the return value of the handler for the current dialect.
import { useDialect } from "nitro-drizzle/runtime";
const result = await useDialect("content", {
sqlite: (datasource) => {
return datasource.database.select().from(schema.posts).all();
},
postgresql: (datasource) => {
return datasource.database.select().from(schema.posts).all();
},
});- Purpose: Helper function to define Drizzle configuration files (
drizzle.config.ts) that are compatible with bothnitro-drizzleanddrizzle-kit. It handles path resolution automatically. - Parameters:
config: Your DrizzleKit configuration object.filename: Passimport.meta.urlas thefilenamefor correct relative path resolution.
- Returns: A DrizzleKit compatible configuration object.
// drizzle.config.ts
import { defineConfig } from "nitro-drizzle/config";
export default defineConfig(
{
dialect: "sqlite",
out: "./migrations",
schema: ["./schema.ts"],
},
import.meta.url,
);- Purpose: Runs Drizzle migrations for a specific datasource. This is typically used internally by the Nitro task, but can be called directly if needed.
- Parameters:
name: The name of the datasource to migrate.
- Returns: A
Promisethat resolves to aMigrationResultobject.
import { migrate } from "nitro-drizzle/migrations";
await migrate("myDatasourceName");- Install dependencies:
pnpm install- Run the unit tests:
pnpm test- Build the library:
pnpm build- Run the playground in development mode:
pnpm playground