Back to Nuxt.js

nuxthub

NuxtNuxtHubFull-stackDrizzle ORMDatabaseKV storageBlob storageCloudflareVercelCaching
682🕒 2026-06-01Source ↗

Install this skill

npx skills add onmax/nuxt-skills

Works across Claude Code, Cursor, Codex, Copilot & Antigravity

NuxtHub provides an integrated backend platform for Nuxt applications, handling database management, key-value storage, and blob file uploads across various cloud environments. By abstracting infrastructure via native Nuxt modules, it enables server-side code to access consistent data APIs without managing separate cloud vendor SDKs. It includes an embedded Drizzle ORM implementation for type-safe SQL interactions, supporting SQLite, PostgreSQL, and MySQL dialects. Developers can transition between local emulation and production environments like Cloudflare D1 or Turso using simple configuration toggles. The framework handles migrations automatically during build and development cycles, simplifying the management of application state. It acts as a unified layer for stateful Nuxt apps, centralizing operations for persistent storage and file handling within the server folder.

When to Use This Skill

  • Building full-stack Nuxt applications requiring persistent SQL storage
  • Implementing caching layers or session management using KV storage
  • Creating file upload features for user profile images or document storage
  • Developing multi-cloud portable apps that switch between providers like Cloudflare, Vercel, or Netlify
  • Managing structured application state with auto-generated database schemas

How to Invoke This Skill

Example prompts that trigger this skill in Claude Code, Cursor, or Antigravity:

  • How do I setup a database for my Nuxt app using NuxtHub?
  • Show me how to perform CRUD operations with Drizzle in NuxtHub
  • Configure NuxtHub to connect to a production D1 database
  • Upload a file to blob storage in a Nuxt 3 server route
  • How to manage migrations automatically in NuxtHub

Pro Tips

  • 💡When facing local vs. production data discrepancies, instruct the agent to enable `remote: true` in `hub` config for testing with live Cloudflare bindings during development.
  • 💡For complex database operations, combine this skill with a general `drizzle-orm` skill to leverage advanced query building and schema definition.
  • 💡Always specify the exact NuxtHub version (e.g., v0.10.4) in your prompts to ensure the most accurate and up-to-date advice from the skill.

What this skill does

  • Type-safe SQL database management with automatic Drizzle ORM integration
  • Unified Key-Value store with TTL support and multi-provider compatibility
  • Blob storage interface for handling file uploads and public/private access
  • Automated migration orchestration for production database synchronization
  • Remote mode for live-testing production database bindings during development

When not to use it

  • Applications that do not use Nuxt as the primary framework
  • Projects requiring heavy custom microservice architectures outside of the Nuxt server directory
  • Systems needing specialized non-relational database features not covered by standard SQL dialects

Example workflow

  1. Add the module using npx nuxi module add hub
  2. Define your SQL schema inside the server/db directory
  3. Run db generate to create migration files based on the schema
  4. Access the db object directly in your API routes without manual imports
  5. Execute insert or select queries to manage application data
  6. Deploy to a cloud provider and let NuxtHub handle migration application

Prerequisites

  • Nuxt 3 project
  • Node.js environment

Pitfalls & limitations

  • !Migrations are tracked automatically in a specific database table, which may conflict if manual SQL changes are made outside the CLI
  • !Production database providers require specific environment variables to be set correctly, unlike local SQLite
  • !Direct local filesystem emulation works differently than cloud R2/D1 production behavior, despite remote mode

FAQ

Does NuxtHub support PostgreSQL?
Yes, it supports PostgreSQL alongside SQLite and MySQL through Drizzle ORM configuration.
Can I use my production database locally?
Yes, by setting remote: true in your hub configuration, the app will connect to your actual production bindings during development.
Do I need to import database clients manually?
No, NuxtHub provides auto-imported db and schema objects directly from the hub:db alias.

How it compares

Unlike setting up individual cloud SDKs or third-party ORMs manually, NuxtHub standardizes the configuration and auto-imports required for these services, maintaining a consistent API regardless of the underlying infrastructure provider.

Source & trust

682 stars🕒 Updated 2026-06-01
📄 Full skill instructions — original source: onmax/nuxt-skills
# NuxtHub v0.10.4

Full-stack Nuxt framework with database, KV, blob, and cache. Multi-cloud support (Cloudflare, Vercel, Deno, Netlify).

**For Nuxt server patterns:** use nuxt skill (server.md)
**For content with database:** use nuxt-content skill

## Installation

npx nuxi module add hub


## Configuration

// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxthub/core'],
hub: {
db: 'sqlite', // 'sqlite' | 'postgresql' | 'mysql'
kv: true,
blob: true,
cache: true,
dir: '.data', // local storage directory
remote: false // use production bindings in dev (v0.10.4+)
}
})


### Advanced Config

hub: {
db: {
dialect: 'postgresql',
driver: 'postgres-js', // Optional: auto-detected
casing: 'snake_case', // camelCase JS -> snake_case DB
migrationsDirs: ['server/db/custom-migrations/'],
applyMigrationsDuringBuild: true // default
},
remote: true // Use production Cloudflare bindings in dev (v0.10.4+)
}


**remote mode:** When enabled, connects to production D1/KV/R2 during local development instead of local emulation. Useful for testing with production data.

## Database

Type-safe SQL via Drizzle ORM. db and schema are auto-imported on server-side.

### Schema Definition

Place in server/db/schema.ts or server/db/schema/*.ts:

// server/db/schema.ts (SQLite)
import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core'

export const users = sqliteTable('users', {
id: integer().primaryKey({ autoIncrement: true }),
name: text().notNull(),
email: text().notNull().unique(),
createdAt: integer({ mode: 'timestamp' }).notNull()
})


PostgreSQL variant:

import { pgTable, serial, text, timestamp } from 'drizzle-orm/pg-core'

export const users = pgTable('users', {
id: serial().primaryKey(),
name: text().notNull(),
email: text().notNull().unique(),
createdAt: timestamp().notNull().defaultNow()
})


### Database API

// db and schema are auto-imported on server-side
import { db, schema } from 'hub:db'

// Select
const users = await db.select().from(schema.users)
const user = await db.query.users.findFirst({ where: eq(schema.users.id, 1) })

// Insert
const [newUser] = await db.insert(schema.users).values({ name: 'John', email: '[email protected]' }).returning()

// Update
await db.update(schema.users).set({ name: 'Jane' }).where(eq(schema.users.id, 1))

// Delete
await db.delete(schema.users).where(eq(schema.users.id, 1))


### Migrations

npx nuxt db generate                  # Generate migrations from schema
npx nuxt db migrate # Apply pending migrations
npx nuxt db sql "SELECT * FROM users" # Execute raw SQL
npx nuxt db drop <TABLE> # Drop a specific table
npx nuxt db drop-all # Drop all tables (v0.10.4+)
npx nuxt db squash # Squash migrations into one (v0.10.4+)
npx nuxt db mark-as-migrated [NAME] # Mark as migrated without running


Migrations auto-apply during npx nuxi dev and npx nuxi build. Tracked in _hub_migrations table.

### Database Providers

| Dialect | Local | Production |
| ---------- | -------------------- | ----------------------------------------------------------------- |
| sqlite | .data/db/sqlite.db | D1 (Cloudflare), Turso (TURSO_DATABASE_URL, TURSO_AUTH_TOKEN) |
| postgresql | PGlite | postgres-js (DATABASE_URL), neon-http (DATABASE_URL) |
| mysql | - | mysql2 (DATABASE_URL, MYSQL_URL) |

## KV Storage

Key-value storage. kv is auto-imported on server-side.

import { kv } from 'hub:kv'

await kv.set('key', { data: 'value' })
await kv.set('key', value, { ttl: 60 }) // TTL in seconds
const value = await kv.get('key')
const exists = await kv.has('key')
await kv.del('key')
const keys = await kv.keys('prefix:')
await kv.clear('prefix:')


Constraints: max value 25 MiB, max key 512 bytes.

### KV Providers

| Provider | Package | Env Vars |
| ------------- | ---------------- | ---------------------------------------------------- |
| Upstash | @upstash/redis | UPSTASH_REDIS_REST_URL, UPSTASH_REDIS_REST_TOKEN |
| Redis | ioredis | REDIS_URL |
| Cloudflare KV | - | KV binding in wrangler.jsonc |
| Deno KV | - | Auto on Deno Deploy |
| Vercel | - | KV_REST_API_URL, KV_REST_API_TOKEN |

## Blob Storage

File storage. blob is auto-imported on server-side.

### Blob API

import { blob } from 'hub:blob'

// Upload
const result = await blob.put('path/file.txt', body, {
contentType: 'text/plain',
access: 'public', // 'public' | 'private' (v0.10.4+)
addRandomSuffix: true,
prefix: 'uploads'
})
// Returns: { pathname, contentType, size, httpEtag, uploadedAt }

// Download
const file = await blob.get('path/file.txt') // Returns Blob or null

// List
const { blobs, cursor, hasMore, folders } = await blob.list({ prefix: 'uploads/', limit: 10, folded: true })

// Serve (with proper headers)
return blob.serve(event, 'path/file.txt')

// Delete
await blob.del('path/file.txt')
await blob.del(['file1.txt', 'file2.txt']) // Multiple

// Metadata only
const meta = await blob.head('path/file.txt')


### Upload Helpers

// Server: Validate + upload handler
export default eventHandler(async (event) => {
return blob.handleUpload(event, {
formKey: 'files',
multiple: true,
ensure: { maxSize: '10MB', types: ['image/png', 'image/jpeg'] },
put: { addRandomSuffix: true, prefix: 'images' }
})
})

// Validate before manual upload
ensureBlob(file, { maxSize: '10MB', types: ['image'] })

// Multipart upload for large files (>10MB)
export default eventHandler(async (event) => {
return blob.handleMultipartUpload(event) // Route: /api/files/multipart/[action]/[...pathname]
})


### Vue Composables

// Simple upload
const upload = useUpload('/api/upload')
const result = await upload(inputElement)

// Multipart with progress
const mpu = useMultipartUpload('/api/files/multipart')
const { completed, progress, abort } = mpu(file)


### Blob Providers

| Provider | Package | Config |
| ------------- | -------------- | -------------------------------------------------------------------- |
| Cloudflare R2 | - | BLOB binding in wrangler.jsonc |
| Vercel Blob | @vercel/blob | BLOB_READ_WRITE_TOKEN |
| S3 | aws4fetch | S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_BUCKET, S3_REGION |

## Cache

Response and function caching.

### Route Handler Caching

export default cachedEventHandler((event) => {
return { data: 'cached', date: new Date().toISOString() }
}, {
maxAge: 60 * 60, // 1 hour
getKey: event => event.path
})


### Function Caching

export const getStars = defineCachedFunction(
async (event: H3Event, repo: string) => {
const data = await $fetch(https://api.github.com/repos/${repo})
return data.stargazers_count
},
{ maxAge: 3600, name: 'ghStars', getKey: (event, repo) => repo }
)


### Cache Invalidation

// Remove specific
await useStorage('cache').removeItem('nitro:functions:getStars:repo-name.json')

// Clear by prefix
await useStorage('cache').clear('nitro:handlers')


Cache key pattern: ${group}:${name}:${getKey(...args)}.json (defaults: group='nitro', name='handlers'|'functions'|'routes')

## Deployment

### Cloudflare

NuxtHub auto-generates wrangler.json from your hub config - no manual wrangler.jsonc required:

// nuxt.config.ts
export default defineNuxtConfig({
hub: {
db: {
dialect: 'sqlite',
driver: 'd1',
connection: { databaseId: '<database-id>' }
},
kv: {
driver: 'cloudflare-kv-binding',
namespaceId: '<kv-namespace-id>'
},
cache: {
driver: 'cloudflare-kv-binding',
namespaceId: '<cache-namespace-id>'
},
blob: {
driver: 'cloudflare-r2',
bucketName: '<bucket-name>'
}
}
})


**Observability (recommended):** Enable logging for production deployments:

// wrangler.jsonc (optional)
{
"observability": {
"logs": {
"enabled": true,
"head_sampling_rate": 1,
"invocation_logs": true,
"persist": true
}
}
}


Create resources via Cloudflare dashboard or CLI:

npx wrangler d1 create my-db              # Get database-id
npx wrangler kv namespace create KV # Get kv-namespace-id
npx wrangler kv namespace create CACHE # Get cache-namespace-id
npx wrangler r2 bucket create my-bucket # Get bucket-name


Deploy: Create [Cloudflare Workers project](https://dash.cloudflare.com/?to=/:account/workers-and-pages/create), link Git repo. Bindings auto-configured at build time.

**Environments:** Use CLOUDFLARE_ENV=preview for preview deployments.

See [references/wrangler-templates.md](references/wrangler-templates.md) for manual wrangler.jsonc patterns and [references/providers.md](references/providers.md) for all provider configurations.

### Other Providers

See [references/providers.md](references/providers.md) for detailed deployment patterns for:

- **Vercel:** Postgres, Turso, Vercel Blob, Vercel KV
- **Netlify:** External databases, S3, Upstash Redis
- **Deno Deploy:** Deno KV
- **AWS/Self-hosted:** S3, RDS, custom configs

### D1 over HTTP

Query D1 from non-Cloudflare hosts:

hub: {
db: { dialect: 'sqlite', driver: 'd1-http' }
}


Requires: NUXT_HUB_CLOUDFLARE_ACCOUNT_ID, NUXT_HUB_CLOUDFLARE_API_TOKEN, NUXT_HUB_CLOUDFLARE_DATABASE_ID

## Build-time Hooks

// Extend schema
nuxt.hook('hub:db:schema:extend', async ({ dialect, paths }) => {
paths.push(await resolvePath(./schema/custom.${dialect}))
})

// Add migration directories
nuxt.hook('hub:db:migrations:dirs', (dirs) => {
dirs.push(resolve('./db-migrations'))
})

// Post-migration queries (idempotent)
nuxt.hook('hub:db:queries:paths', (paths, dialect) => {
paths.push(resolve(./seed.${dialect}.sql))
})


## Type Sharing

// shared/types/db.ts
import type { users } from '~/server/db/schema'

export type User = typeof users.$inferSelect
export type NewUser = typeof users.$inferInsert


## WebSocket / Realtime

Enable experimental WebSocket:

// nuxt.config.ts
nitro: { experimental: { websocket: true } }


// server/routes/ws/chat.ts
export default defineWebSocketHandler({
open(peer) {
peer.subscribe('chat')
peer.publish('chat', 'User joined')
},
message(peer, message) {
peer.publish('chat', message.text())
},
close(peer) {
peer.unsubscribe('chat')
}
})


## Deprecated (v0.10)

Removed Cloudflare-specific features:

- hubAI() -> Use AI SDK with Workers AI Provider
- hubBrowser() -> Puppeteer
- hubVectorize() -> Vectorize
- NuxtHub Admin -> Sunset Dec 31, 2025
- npx nuxthub deploy -> Use wrangler deploy

## Quick Reference

| Feature | Import | Access |
| -------- | ------------------------------------- | ---------------------------------- |
| Database | import { db, schema } from 'hub:db' | db.select(), db.insert(), etc. |
| KV | import { kv } from 'hub:kv' | kv.get(), kv.set(), etc. |
| Blob | import { blob } from 'hub:blob' | blob.put(), blob.get(), etc. |

All are auto-imported on server-side.

## Resources

- [Installation](https://hub.nuxt.com/docs/getting-started/installation)
- [Migration from v0.9](https://hub.nuxt.com/docs/getting-started/migration)
- [Database](https://hub.nuxt.com/docs/database)
- [Blob](https://hub.nuxt.com/docs/blob)
- [KV](https://hub.nuxt.com/docs/kv)
- [Cache](https://hub.nuxt.com/docs/cache)
- [Deploy](https://hub.nuxt.com/docs/getting-started/deploy)

How to Use This Skill Unit

Option A: Project-Specific (Recommended)

  1. Click "Download" above
  2. In your project, create the directory: .agent/skills/nuxthub/
  3. Save the file as SKILL.md
  4. The agent will automatically discover the skill based on its description.

Option B: Global Installation (All Agents)

Save the file to these locations to make it available across all projects:

  • Claude Code: ~/.claude/skills/onmax/nuxt-skills/nuxthub/SKILL.md
  • Cursor: ~/.cursor/skills/onmax/nuxt-skills/nuxthub/SKILL.md
  • Antigravity: ~/.gemini/antigravity/skills/onmax/nuxt-skills/nuxthub/SKILL.md

🚀 Install with CLI:
npx skills add onmax/nuxt-skills

Read the Master Guide: Mastering Agent Skills

Related Skill Units

Recommended Rules

View more rules

Recommended Workflows

View more workflows

Recommended MCP Servers

View more MCP servers

Take It Further

Maximize your productivity with these powerful resources

📋

Define Your Standards

Set up coding standards to ensure this workflow produces consistent, high-quality results.

Browse Rules Library
📖

Master Workflows

Learn how to create custom workflows, use Turbo Mode, and build your automation library.

Complete Guide

How to use this Skill in Claude Code & Cursor

For Claude Code (CLI)

To use this skill in Claude Code, copy the rule content into your project's custom instructions or follow our Add-Skill CLI guide. This ensures Claude follows your standards during every code generation.

For Cursor & Windsurf

For Cursor or Windsurf, individual skills are best used in the "Rules for AI" section. This specific unit helps the agent avoid nuxt.js issues, leading to cleaner, more efficient code.

Why the skill format matters: the standardized Agent Skills format lets your AI agent load detailed instructions only when they are relevant, keeping your prompt clean while improving results.

Source & attribution

This skill is categorized under Nuxt.js and is published by Onmax, maintained in onmax/nuxt-skills.

← Browse All Agent Skills
Sponsored AI assistant. Recommendations may be paid.