Database Queries

Learn how to read and write data using Drizzle ORM in Nuxt, including filtering, joining, and aggregating relational data safely and efficiently.

Now that you have your database schema and migrations set up, you can start querying your database.

Importing the database

NuxtHub provides two ways to import the database client:

Use @nuxthub/db to import the database client. This works everywhere, including in Nuxt server routes and external bundlers like Workflow:

import { db, schema } from '@nuxthub/db'
This is the recommended approach as it works with both Nuxt and external tools that bundle your code independently.

Legacy: hub:db

The virtual module hub:db is still supported for backwards compatibility (Nuxt only):

import { db, schema } from 'hub:db'
db and schema are auto-imported on the server-side, so you can use them directly without importing.

SQL Select

server/api/users.get.ts
import { db, schema } from '@nuxthub/db'

export default eventHandler(async (event) => {
  return await db.query.users.findMany()
  // or
  return await db.select().from(schema.users)
})
Learn more about Drizzle ORM select on the Drizzle documentation.

SQL Insert

server/api/users.post.ts
import { db, schema } from '@nuxthub/db'

export default eventHandler(async (event) => {
  const { name, email } = await readBody(event)

  return await db
    .insert(schema.users)
    .values({
      name,
      email,
      createdAt: new Date()
    })
    .returning()
})
Learn more about Drizzle ORM insert on the Drizzle documentation.

SQL Update

server/api/users/[id].patch.ts
import { db, schema } from '@nuxthub/db'

export default eventHandler(async (event) => {
  const { id } = getRouterParams(event)
  const { name } = await readBody(event)

  return await db
    .update(schema.users)
    .set({ name })
    .where(eq(tables.users.id, Number(id)))
    .returning()
})
Learn more about Drizzle ORM update on the Drizzle documentation.

SQL Delete

server/api/users/[id].delete.ts
import { db, schema } from '@nuxthub/db'

export default eventHandler(async (event) => {
  const { id } = getRouterParams(event)

  const deletedUser = await db
    .delete(schema.users)
    .where(eq(schema.users.id, Number(id)))
    .returning()

  if (!deletedUser) {
    throw createError({
      statusCode: 404,
      message: 'User not found'
    })
  }

  return { deleted: true }
})
Learn more about Drizzle ORM delete on the Drizzle documentation.

Using with external bundlers

The @nuxthub/db import works seamlessly with external tools that bundle your code independently, such as Workflow.

Example with Workflow

Workflow is a library for building and running durable, reliable, and scalable background jobs in TypeScript. Here's how to use NuxtHub Database with Workflow:

workflow/tasks/cleanup-inactive-users.ts
import { db, schema } from '@nuxthub/db'
import { lt } from 'drizzle-orm'

export default async function cleanupInactiveUsers() {
  // Delete users who haven't logged in for 90 days
  const ninetyDaysAgo = new Date(Date.now() - 90 * 24 * 60 * 60 * 1000)

  const deleted = await db
    .delete(schema.users)
    .where(lt(schema.users.lastLoginAt, ninetyDaysAgo))
    .returning()

  return {
    deletedCount: deleted.length,
    deletedUserIds: deleted.map(u => u.id)
  }
}

How it works

When you build your Nuxt application:

  1. NuxtHub generates the database client at node_modules/@nuxthub/db/
  2. This physical module contains your compiled database schema and client
  3. External bundlers like Workflow can import and bundle this module directly
  4. The hub:db virtual module remains available for Nuxt server routes (backwards compatibility)
The @nuxthub/db package is auto-generated during development and build. You don't need to add it to your package.json.

Benefits

  • Universal compatibility: Works with Nuxt server routes, Workflow tasks, and any other TypeScript code
  • Type-safe: Full TypeScript support with auto-generated types
  • No configuration: Automatically synced when you run nuxt dev or nuxt build
  • Single source of truth: Your server/db/schema.ts files are the only place you define your schema