Sets up NuxtHub modules for server-side state, including Drizzle ORM, KV storage, and blob management for Cloudflare and Vercel.
Install
mkdir -p .claude/skills/nuxthub && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/2840" && unzip -o skill.zip -d .claude/skills/nuxthub && rm skill.zipInstalls to .claude/skills/nuxthub
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Use when building NuxtHub v0.10.6 applications - provides database (Drizzle ORM with sqlite/postgresql/mysql), KV storage, blob storage, and cache APIs. Covers configuration, schema definition, migrations, multi-cloud deployment (Cloudflare, Vercel), and the new hub:db, hub:kv, hub:blob virtual module imports.Key capabilities
- →Configures hub:db with sqlite/postgres/mysql drivers
- →Manages virtual module imports for KV and blob storage
- →Enables remote production-binding emulation in local development
- →Automates schema migration application during build
- →Sets up read-replica database connection strings
How it works
It modifies nuxt.config.ts and manages environment-specific drivers to align Nuxt server patterns with multi-cloud storage APIs.
Inputs & outputs
When to use nuxthub
- →Configuring NuxtHub database with Drizzle
- →Implementing KV storage in Nuxt
- →Deploying NuxtHub apps to Cloudflare
- →Setting up blob storage
About this skill
NuxtHub v0.10.6
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
Loading Files
Consider loading these reference files based on your task:
- references/wrangler-templates.md - if manually configuring wrangler.jsonc for Cloudflare deployment
- references/providers.md - if deploying to Vercel, Netlify, Deno, AWS, or configuring external database/storage providers
DO NOT load all files at once. Load only what's relevant to your current task.
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+)
}
})
Advanced Config
hub: {
db: {
dialect: 'postgresql',
driver: 'postgres-js', // Optional: auto-detected
casing: 'snake_case', // camelCase JS -> snake_case DB (v0.10.3+)
migrationsDirs: ['server/db/custom-migrations/'],
applyMigrationsDuringBuild: true, // default
replica: { // Read replica support (v0.10.6+)
connection: { connectionString: process.env.DATABASE_REPLICA_URL }
}
},
remote: true // Use production Cloudflare bindings in dev (v0.10+)
}
remote mode: When enabled, connects to production D1/KV/R2 during local development instead of local emulation. Useful for testing with production data.
Database replica (v0.10.6+): Configure read replicas to distribute database load. Queries use replicas automatically while writes go to primary.
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+)
npx nuxt db squash # Squash migrations into one (v0.10+)
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 (v0.10.2+, 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.2+)
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, link Git repo. Bindings auto-configured at build time.
**Environm
Content truncated.
When not to use it
- →Standard Nuxt applications without NuxtHub requirements
- →Projects requiring non-Hub native SQL drivers
Prerequisites
Limitations
- →Limited to NuxtHub v0.10.6+ architecture
- →Dependent on environment-specific provider capabilities
How it compares
It focuses on the specific virtual module system of NuxtHub rather than generic database ORM implementation.
Compared to similar skills
nuxthub side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| nuxthub (this skill) | 1 | 6mo | Review | Intermediate |
| qruiq-google-auth | 0 | 4mo | Review | Intermediate |
| server-action-pattern | 0 | 2mo | No flags | Intermediate |
| nextjs-chatbot | 0 | 2mo | No flags | Advanced |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by onmax
View all by onmax →You might also like
qruiq-google-auth
qruiqai
|
server-action-pattern
JKKN-Institutions
Create or modify a Next.js Server Action for the JKKN institution website following the project's mandatory pattern. This skill should be used when the user asks to "add a server action", "create a mutation", "wire up a form submit", "add create/update/delete logic", "save/update/delete an entity",
nextjs-chatbot
laguagu
Advanced patterns for production Next.js web chatbots built with AI SDK 6 + ai-elements. Covers tool calling with human-in-the-loop (HITL) approval, PostgreSQL session persistence, GDPR consent gating, SQL-first search, per-tool UI rendering, popup widget embedding, message feedback, follow-up sugge
add-feature
jujunjun110
新しい機能を追加する。ユーザーが機能の説明をしたとき、DDD4層に従って全レイヤーのファイルを生成する
payload
payloadcms
Use when working with Payload CMS projects (payload.config.ts, collections, fields, hooks, access control, Payload API). Use when debugging validation errors, security issues, relationship queries, transactions, or hook behavior.
drizzle-orm
EpicenterHQ
Drizzle ORM patterns for type branding and custom types. Use when working with Drizzle column definitions, branded types, or custom type conversions.