[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CSXZYN8Z17KV72RMZXX5AF":3,"skill-same:01M6CSXZYN8Z17KV72RMZXX5AF":77},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":26,"publishedAt":43,"linkOnly":44,"markdownContent":45,"markdownBody":46,"frontMatter":47,"refName":49,"commitSha":50,"skillDirectory":51,"forksCount":52,"repositoryHtmlUrl":53,"repositoryHomepageUrl":53,"ownerHtmlUrl":54,"ownerBlogUrl":6,"ownerDescription":55,"updatedAt":56,"install":57,"resources":70},"01M6CSXZYN8Z17KV72RMZXX5AF","drizzle-orm-expert",null,"Expert in Drizzle ORM for TypeScript — schema design, relational queries, migrations, and serverless database integration. Use when building type-safe database layers with Drizzle.","Sam-06060\u002Fjarvis-assistant","Sam-06060","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F208600848?v=4","01M6CRKT7C7FXD21V6HXF293S0","Samson Frank Ganta","01M6CRKTBEKYFD8YX5Z1GT99EE",6,"Apache-2.0","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fdrizzle-orm-expert\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000015","视觉设计",[27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42],"drizzle orm expert","orm","drizzle orm","expert","design","safe","typescript","database","integration","serverless","use","schema","schema design","queries","migrations","community","2026-11-10 10:12:30",false,"---\nname: drizzle-orm-expert\ndescription: \"Expert in Drizzle ORM for TypeScript — schema design, relational queries, migrations, and serverless database integration. Use when building type-safe database layers with Drizzle.\"\nrisk: safe\nsource: community\ndate_added: \"2026-03-04\"\n---\n\n# Drizzle ORM Expert\n\nYou are a production-grade Drizzle ORM expert. You help developers build type-safe, performant database layers using Drizzle ORM with TypeScript. You know schema design, the relational query API, Drizzle Kit migrations, and integrations with Next.js, tRPC, and serverless databases (Neon, PlanetScale, Turso, Supabase).\n\n## When to Use This Skill\n\n- Use when the user asks to set up Drizzle ORM in a new or existing project\n- Use when designing database schemas with Drizzle's TypeScript-first approach\n- Use when writing complex relational queries (joins, subqueries, aggregations)\n- Use when setting up or troubleshooting Drizzle Kit migrations\n- Use when integrating Drizzle with Next.js App Router, tRPC, or Hono\n- Use when optimizing database performance (prepared statements, batching, connection pooling)\n- Use when migrating from Prisma, TypeORM, or Knex to Drizzle\n\n## Core Concepts\n\n### Why Drizzle\n\nDrizzle ORM is a TypeScript-first ORM that generates zero runtime overhead. Unlike Prisma (which uses a query engine binary), Drizzle compiles to raw SQL — making it ideal for edge runtimes and serverless. Key advantages:\n\n- **SQL-like API**: If you know SQL, you know Drizzle\n- **Zero dependencies**: Tiny bundle, works in Cloudflare Workers, Vercel Edge, Deno\n- **Full type inference**: Schema → types → queries are all connected at compile time\n- **Relational Query API**: Prisma-like nested includes without N+1 problems\n\n## Schema Design Patterns\n\n### Table Definitions\n\n```typescript\n\u002F\u002F db\u002Fschema.ts\nimport { pgTable, text, integer, timestamp, boolean, uuid, pgEnum } from \"drizzle-orm\u002Fpg-core\";\nimport { relations } from \"drizzle-orm\";\n\n\u002F\u002F Enums\nexport const roleEnum = pgEnum(\"role\", [\"admin\", \"user\", \"moderator\"]);\n\n\u002F\u002F Users table\nexport const users = pgTable(\"users\", {\n  id: uuid(\"id\").defaultRandom().primaryKey(),\n  email: text(\"email\").notNull().unique(),\n  name: text(\"name\").notNull(),\n  role: roleEnum(\"role\").default(\"user\").notNull(),\n  createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n  updatedAt: timestamp(\"updated_at\").defaultNow().notNull(),\n});\n\n\u002F\u002F Posts table with foreign key\nexport const posts = pgTable(\"posts\", {\n  id: uuid(\"id\").defaultRandom().primaryKey(),\n  title: text(\"title\").notNull(),\n  content: text(\"content\"),\n  published: boolean(\"published\").default(false).notNull(),\n  authorId: uuid(\"author_id\").references(() => users.id, { onDelete: \"cascade\" }).notNull(),\n  createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n});\n```\n\n### Relations\n\n```typescript\n\u002F\u002F db\u002Frelations.ts\nexport const usersRelations = relations(users, ({ many }) => ({\n  posts: many(posts),\n}));\n\nexport const postsRelations = relations(posts, ({ one }) => ({\n  author: one(users, {\n    fields: [posts.authorId],\n    references: [users.id],\n  }),\n}));\n```\n\n### Type Inference\n\n```typescript\n\u002F\u002F Infer types directly from your schema — no separate type files needed\nimport type { InferSelectModel, InferInsertModel } from \"drizzle-orm\";\n\nexport type User = InferSelectModel\u003Ctypeof users>;\nexport type NewUser = InferInsertModel\u003Ctypeof users>;\nexport type Post = InferSelectModel\u003Ctypeof posts>;\nexport type NewPost = InferInsertModel\u003Ctypeof posts>;\n```\n\n## Query Patterns\n\n### Select Queries (SQL-like API)\n\n```typescript\nimport { eq, and, like, desc, count, sql } from \"drizzle-orm\";\n\n\u002F\u002F Basic select\nconst allUsers = await db.select().from(users);\n\n\u002F\u002F Filtered with conditions\nconst admins = await db.select().from(users).where(eq(users.role, \"admin\"));\n\n\u002F\u002F Partial select (only specific columns)\nconst emails = await db.select({ email: users.email }).from(users);\n\n\u002F\u002F Join query\nconst postsWithAuthors = await db\n  .select({\n    title: posts.title,\n    authorName: users.name,\n  })\n  .from(posts)\n  .innerJoin(users, eq(posts.authorId, users.id))\n  .where(eq(posts.published, true))\n  .orderBy(desc(posts.createdAt))\n  .limit(10);\n\n\u002F\u002F Aggregation\nconst postCounts = await db\n  .select({\n    authorId: posts.authorId,\n    postCount: count(posts.id),\n  })\n  .from(posts)\n  .groupBy(posts.authorId);\n```\n\n### Relational Queries (Prisma-like API)\n\n```typescript\n\u002F\u002F Nested includes — Drizzle resolves in a single query\nconst usersWithPosts = await db.query.users.findMany({\n  with: {\n    posts: {\n      where: eq(posts.published, true),\n      orderBy: [desc(posts.createdAt)],\n      limit: 5,\n    },\n  },\n});\n\n\u002F\u002F Find one with nested data\nconst user = await db.query.users.findFirst({\n  where: eq(users.id, userId),\n  with: { posts: true },\n});\n```\n\n### Insert, Update, Delete\n\n```typescript\n\u002F\u002F Insert with returning\nconst [newUser] = await db\n  .insert(users)\n  .values({ email: \"dev@example.com\", name: \"Dev\" })\n  .returning();\n\n\u002F\u002F Batch insert\nawait db.insert(posts).values([\n  { title: \"Post 1\", authorId: newUser.id },\n  { title: \"Post 2\", authorId: newUser.id },\n]);\n\n\u002F\u002F Update\nawait db.update(users).set({ name: \"Updated\" }).where(eq(users.id, userId));\n\n\u002F\u002F Delete\nawait db.delete(posts).where(eq(posts.authorId, userId));\n```\n\n### Transactions\n\n```typescript\nconst result = await db.transaction(async (tx) => {\n  const [user] = await tx.insert(users).values({ email, name }).returning();\n  await tx.insert(posts).values({ title: \"Welcome Post\", authorId: user.id });\n  return user;\n});\n```\n\n## Migration Workflow (Drizzle Kit)\n\n### Configuration\n\n```typescript\n\u002F\u002F drizzle.config.ts\nimport { defineConfig } from \"drizzle-kit\";\n\nexport default defineConfig({\n  schema: \".\u002Fdb\u002Fschema.ts\",\n  out: \".\u002Fdrizzle\",\n  dialect: \"postgresql\",\n  dbCredentials: {\n    url: process.env.DATABASE_URL!,\n  },\n});\n```\n\n### Commands\n\n```bash\n# Generate migration SQL from schema changes\nnpx drizzle-kit generate\n\n# Push schema directly to database (development only — skips migration files)\nnpx drizzle-kit push\n\n# Run pending migrations (production)\nnpx drizzle-kit migrate\n\n# Open Drizzle Studio (GUI database browser)\nnpx drizzle-kit studio\n```\n\n## Database Client Setup\n\n### PostgreSQL (Neon Serverless)\n\n```typescript\n\u002F\u002F db\u002Findex.ts\nimport { drizzle } from \"drizzle-orm\u002Fneon-http\";\nimport { neon } from \"@neondatabase\u002Fserverless\";\nimport * as schema from \".\u002Fschema\";\n\nconst sql = neon(process.env.DATABASE_URL!);\nexport const db = drizzle(sql, { schema });\n```\n\n### SQLite (Turso\u002FLibSQL)\n\n```typescript\nimport { drizzle } from \"drizzle-orm\u002Flibsql\";\nimport { createClient } from \"@libsql\u002Fclient\";\nimport * as schema from \".\u002Fschema\";\n\nconst client = createClient({\n  url: process.env.TURSO_DATABASE_URL!,\n  authToken: process.env.TURSO_AUTH_TOKEN,\n});\nexport const db = drizzle(client, { schema });\n```\n\n### MySQL (PlanetScale)\n\n```typescript\nimport { drizzle } from \"drizzle-orm\u002Fplanetscale-serverless\";\nimport { Client } from \"@planetscale\u002Fdatabase\";\nimport * as schema from \".\u002Fschema\";\n\nconst client = new Client({ url: process.env.DATABASE_URL! });\nexport const db = drizzle(client, { schema });\n```\n\n## Performance Optimization\n\n### Prepared Statements\n\n```typescript\n\u002F\u002F Prepare once, execute many times\nconst getUserById = db.query.users\n  .findFirst({\n    where: eq(users.id, sql.placeholder(\"id\")),\n  })\n  .prepare(\"get_user_by_id\");\n\n\u002F\u002F Execute with parameters\nconst user = await getUserById.execute({ id: \"abc-123\" });\n```\n\n### Batch Operations\n\n```typescript\n\u002F\u002F Use db.batch() for multiple independent queries in one round-trip\nconst [allUsers, recentPosts] = await db.batch([\n  db.select().from(users),\n  db.select().from(posts).orderBy(desc(posts.createdAt)).limit(10),\n]);\n```\n\n### Indexing in Schema\n\n```typescript\nimport { index, uniqueIndex } from \"drizzle-orm\u002Fpg-core\";\n\nexport const posts = pgTable(\n  \"posts\",\n  {\n    id: uuid(\"id\").defaultRandom().primaryKey(),\n    title: text(\"title\").notNull(),\n    authorId: uuid(\"author_id\").references(() => users.id).notNull(),\n    createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n  },\n  (table) => [\n    index(\"posts_author_idx\").on(table.authorId),\n    index(\"posts_created_idx\").on(table.createdAt),\n  ]\n);\n```\n\n## Next.js Integration\n\n### Server Component Usage\n\n```typescript\n\u002F\u002F app\u002Fusers\u002Fpage.tsx (React Server Component)\nimport { db } from \"@\u002Fdb\";\nimport { users } from \"@\u002Fdb\u002Fschema\";\n\nexport default async function UsersPage() {\n  const allUsers = await db.select().from(users);\n  return (\n    \u003Cul>\n      {allUsers.map((u) => (\n        \u003Cli key={u.id}>{u.name}\u003C\u002Fli>\n      ))}\n    \u003C\u002Ful>\n  );\n}\n```\n\n### Server Action\n\n```typescript\n\u002F\u002F app\u002Factions.ts\n\"use server\";\nimport { db } from \"@\u002Fdb\";\nimport { users } from \"@\u002Fdb\u002Fschema\";\n\nexport async function createUser(formData: FormData) {\n  const name = formData.get(\"name\") as string;\n  const email = formData.get(\"email\") as string;\n  await db.insert(users).values({ name, email });\n}\n```\n\n## Best Practices\n\n- ✅ **Do:** Keep all schema definitions in a single `db\u002Fschema.ts` or split by domain (`db\u002Fschema\u002Fusers.ts`, `db\u002Fschema\u002Fposts.ts`)\n- ✅ **Do:** Use `InferSelectModel` and `InferInsertModel` for type safety instead of manual interfaces\n- ✅ **Do:** Use the relational query API (`db.query.*`) for nested data to avoid N+1 problems\n- ✅ **Do:** Use prepared statements for frequently executed queries in production\n- ✅ **Do:** Use `drizzle-kit generate` + `migrate` in production (never `push`)\n- ✅ **Do:** Pass `{ schema }` to `drizzle()` to enable the relational query API\n- ❌ **Don't:** Use `drizzle-kit push` in production — it can cause data loss\n- ❌ **Don't:** Write raw SQL when the Drizzle query builder supports the operation\n- ❌ **Don't:** Forget to define `relations()` if you want to use `db.query.*` with `with`\n- ❌ **Don't:** Create a new database connection per request in serverless — use connection pooling\n\n## Troubleshooting\n\n**Problem:** `db.query.tableName` is undefined\n**Solution:** Pass all schema objects (including relations) to `drizzle()`: `drizzle(client, { schema })`\n\n**Problem:** Migration conflicts after schema changes\n**Solution:** Run `npx drizzle-kit generate` to create a new migration, then `npx drizzle-kit migrate`\n\n**Problem:** Type errors on `.returning()` with MySQL\n**Solution:** MySQL does not support `RETURNING`. Use `.execute()` and read `insertId` from the result instead.\n","# Drizzle ORM Expert\n\nYou are a production-grade Drizzle ORM expert. You help developers build type-safe, performant database layers using Drizzle ORM with TypeScript. You know schema design, the relational query API, Drizzle Kit migrations, and integrations with Next.js, tRPC, and serverless databases (Neon, PlanetScale, Turso, Supabase).\n\n## When to Use This Skill\n\n- Use when the user asks to set up Drizzle ORM in a new or existing project\n- Use when designing database schemas with Drizzle's TypeScript-first approach\n- Use when writing complex relational queries (joins, subqueries, aggregations)\n- Use when setting up or troubleshooting Drizzle Kit migrations\n- Use when integrating Drizzle with Next.js App Router, tRPC, or Hono\n- Use when optimizing database performance (prepared statements, batching, connection pooling)\n- Use when migrating from Prisma, TypeORM, or Knex to Drizzle\n\n## Core Concepts\n\n### Why Drizzle\n\nDrizzle ORM is a TypeScript-first ORM that generates zero runtime overhead. Unlike Prisma (which uses a query engine binary), Drizzle compiles to raw SQL — making it ideal for edge runtimes and serverless. Key advantages:\n\n- **SQL-like API**: If you know SQL, you know Drizzle\n- **Zero dependencies**: Tiny bundle, works in Cloudflare Workers, Vercel Edge, Deno\n- **Full type inference**: Schema → types → queries are all connected at compile time\n- **Relational Query API**: Prisma-like nested includes without N+1 problems\n\n## Schema Design Patterns\n\n### Table Definitions\n\n```typescript\n\u002F\u002F db\u002Fschema.ts\nimport { pgTable, text, integer, timestamp, boolean, uuid, pgEnum } from \"drizzle-orm\u002Fpg-core\";\nimport { relations } from \"drizzle-orm\";\n\n\u002F\u002F Enums\nexport const roleEnum = pgEnum(\"role\", [\"admin\", \"user\", \"moderator\"]);\n\n\u002F\u002F Users table\nexport const users = pgTable(\"users\", {\n  id: uuid(\"id\").defaultRandom().primaryKey(),\n  email: text(\"email\").notNull().unique(),\n  name: text(\"name\").notNull(),\n  role: roleEnum(\"role\").default(\"user\").notNull(),\n  createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n  updatedAt: timestamp(\"updated_at\").defaultNow().notNull(),\n});\n\n\u002F\u002F Posts table with foreign key\nexport const posts = pgTable(\"posts\", {\n  id: uuid(\"id\").defaultRandom().primaryKey(),\n  title: text(\"title\").notNull(),\n  content: text(\"content\"),\n  published: boolean(\"published\").default(false).notNull(),\n  authorId: uuid(\"author_id\").references(() => users.id, { onDelete: \"cascade\" }).notNull(),\n  createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n});\n```\n\n### Relations\n\n```typescript\n\u002F\u002F db\u002Frelations.ts\nexport const usersRelations = relations(users, ({ many }) => ({\n  posts: many(posts),\n}));\n\nexport const postsRelations = relations(posts, ({ one }) => ({\n  author: one(users, {\n    fields: [posts.authorId],\n    references: [users.id],\n  }),\n}));\n```\n\n### Type Inference\n\n```typescript\n\u002F\u002F Infer types directly from your schema — no separate type files needed\nimport type { InferSelectModel, InferInsertModel } from \"drizzle-orm\";\n\nexport type User = InferSelectModel\u003Ctypeof users>;\nexport type NewUser = InferInsertModel\u003Ctypeof users>;\nexport type Post = InferSelectModel\u003Ctypeof posts>;\nexport type NewPost = InferInsertModel\u003Ctypeof posts>;\n```\n\n## Query Patterns\n\n### Select Queries (SQL-like API)\n\n```typescript\nimport { eq, and, like, desc, count, sql } from \"drizzle-orm\";\n\n\u002F\u002F Basic select\nconst allUsers = await db.select().from(users);\n\n\u002F\u002F Filtered with conditions\nconst admins = await db.select().from(users).where(eq(users.role, \"admin\"));\n\n\u002F\u002F Partial select (only specific columns)\nconst emails = await db.select({ email: users.email }).from(users);\n\n\u002F\u002F Join query\nconst postsWithAuthors = await db\n  .select({\n    title: posts.title,\n    authorName: users.name,\n  })\n  .from(posts)\n  .innerJoin(users, eq(posts.authorId, users.id))\n  .where(eq(posts.published, true))\n  .orderBy(desc(posts.createdAt))\n  .limit(10);\n\n\u002F\u002F Aggregation\nconst postCounts = await db\n  .select({\n    authorId: posts.authorId,\n    postCount: count(posts.id),\n  })\n  .from(posts)\n  .groupBy(posts.authorId);\n```\n\n### Relational Queries (Prisma-like API)\n\n```typescript\n\u002F\u002F Nested includes — Drizzle resolves in a single query\nconst usersWithPosts = await db.query.users.findMany({\n  with: {\n    posts: {\n      where: eq(posts.published, true),\n      orderBy: [desc(posts.createdAt)],\n      limit: 5,\n    },\n  },\n});\n\n\u002F\u002F Find one with nested data\nconst user = await db.query.users.findFirst({\n  where: eq(users.id, userId),\n  with: { posts: true },\n});\n```\n\n### Insert, Update, Delete\n\n```typescript\n\u002F\u002F Insert with returning\nconst [newUser] = await db\n  .insert(users)\n  .values({ email: \"dev@example.com\", name: \"Dev\" })\n  .returning();\n\n\u002F\u002F Batch insert\nawait db.insert(posts).values([\n  { title: \"Post 1\", authorId: newUser.id },\n  { title: \"Post 2\", authorId: newUser.id },\n]);\n\n\u002F\u002F Update\nawait db.update(users).set({ name: \"Updated\" }).where(eq(users.id, userId));\n\n\u002F\u002F Delete\nawait db.delete(posts).where(eq(posts.authorId, userId));\n```\n\n### Transactions\n\n```typescript\nconst result = await db.transaction(async (tx) => {\n  const [user] = await tx.insert(users).values({ email, name }).returning();\n  await tx.insert(posts).values({ title: \"Welcome Post\", authorId: user.id });\n  return user;\n});\n```\n\n## Migration Workflow (Drizzle Kit)\n\n### Configuration\n\n```typescript\n\u002F\u002F drizzle.config.ts\nimport { defineConfig } from \"drizzle-kit\";\n\nexport default defineConfig({\n  schema: \".\u002Fdb\u002Fschema.ts\",\n  out: \".\u002Fdrizzle\",\n  dialect: \"postgresql\",\n  dbCredentials: {\n    url: process.env.DATABASE_URL!,\n  },\n});\n```\n\n### Commands\n\n```bash\n# Generate migration SQL from schema changes\nnpx drizzle-kit generate\n\n# Push schema directly to database (development only — skips migration files)\nnpx drizzle-kit push\n\n# Run pending migrations (production)\nnpx drizzle-kit migrate\n\n# Open Drizzle Studio (GUI database browser)\nnpx drizzle-kit studio\n```\n\n## Database Client Setup\n\n### PostgreSQL (Neon Serverless)\n\n```typescript\n\u002F\u002F db\u002Findex.ts\nimport { drizzle } from \"drizzle-orm\u002Fneon-http\";\nimport { neon } from \"@neondatabase\u002Fserverless\";\nimport * as schema from \".\u002Fschema\";\n\nconst sql = neon(process.env.DATABASE_URL!);\nexport const db = drizzle(sql, { schema });\n```\n\n### SQLite (Turso\u002FLibSQL)\n\n```typescript\nimport { drizzle } from \"drizzle-orm\u002Flibsql\";\nimport { createClient } from \"@libsql\u002Fclient\";\nimport * as schema from \".\u002Fschema\";\n\nconst client = createClient({\n  url: process.env.TURSO_DATABASE_URL!,\n  authToken: process.env.TURSO_AUTH_TOKEN,\n});\nexport const db = drizzle(client, { schema });\n```\n\n### MySQL (PlanetScale)\n\n```typescript\nimport { drizzle } from \"drizzle-orm\u002Fplanetscale-serverless\";\nimport { Client } from \"@planetscale\u002Fdatabase\";\nimport * as schema from \".\u002Fschema\";\n\nconst client = new Client({ url: process.env.DATABASE_URL! });\nexport const db = drizzle(client, { schema });\n```\n\n## Performance Optimization\n\n### Prepared Statements\n\n```typescript\n\u002F\u002F Prepare once, execute many times\nconst getUserById = db.query.users\n  .findFirst({\n    where: eq(users.id, sql.placeholder(\"id\")),\n  })\n  .prepare(\"get_user_by_id\");\n\n\u002F\u002F Execute with parameters\nconst user = await getUserById.execute({ id: \"abc-123\" });\n```\n\n### Batch Operations\n\n```typescript\n\u002F\u002F Use db.batch() for multiple independent queries in one round-trip\nconst [allUsers, recentPosts] = await db.batch([\n  db.select().from(users),\n  db.select().from(posts).orderBy(desc(posts.createdAt)).limit(10),\n]);\n```\n\n### Indexing in Schema\n\n```typescript\nimport { index, uniqueIndex } from \"drizzle-orm\u002Fpg-core\";\n\nexport const posts = pgTable(\n  \"posts\",\n  {\n    id: uuid(\"id\").defaultRandom().primaryKey(),\n    title: text(\"title\").notNull(),\n    authorId: uuid(\"author_id\").references(() => users.id).notNull(),\n    createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n  },\n  (table) => [\n    index(\"posts_author_idx\").on(table.authorId),\n    index(\"posts_created_idx\").on(table.createdAt),\n  ]\n);\n```\n\n## Next.js Integration\n\n### Server Component Usage\n\n```typescript\n\u002F\u002F app\u002Fusers\u002Fpage.tsx (React Server Component)\nimport { db } from \"@\u002Fdb\";\nimport { users } from \"@\u002Fdb\u002Fschema\";\n\nexport default async function UsersPage() {\n  const allUsers = await db.select().from(users);\n  return (\n    \u003Cul>\n      {allUsers.map((u) => (\n        \u003Cli key={u.id}>{u.name}\u003C\u002Fli>\n      ))}\n    \u003C\u002Ful>\n  );\n}\n```\n\n### Server Action\n\n```typescript\n\u002F\u002F app\u002Factions.ts\n\"use server\";\nimport { db } from \"@\u002Fdb\";\nimport { users } from \"@\u002Fdb\u002Fschema\";\n\nexport async function createUser(formData: FormData) {\n  const name = formData.get(\"name\") as string;\n  const email = formData.get(\"email\") as string;\n  await db.insert(users).values({ name, email });\n}\n```\n\n## Best Practices\n\n- ✅ **Do:** Keep all schema definitions in a single `db\u002Fschema.ts` or split by domain (`db\u002Fschema\u002Fusers.ts`, `db\u002Fschema\u002Fposts.ts`)\n- ✅ **Do:** Use `InferSelectModel` and `InferInsertModel` for type safety instead of manual interfaces\n- ✅ **Do:** Use the relational query API (`db.query.*`) for nested data to avoid N+1 problems\n- ✅ **Do:** Use prepared statements for frequently executed queries in production\n- ✅ **Do:** Use `drizzle-kit generate` + `migrate` in production (never `push`)\n- ✅ **Do:** Pass `{ schema }` to `drizzle()` to enable the relational query API\n- ❌ **Don't:** Use `drizzle-kit push` in production — it can cause data loss\n- ❌ **Don't:** Write raw SQL when the Drizzle query builder supports the operation\n- ❌ **Don't:** Forget to define `relations()` if you want to use `db.query.*` with `with`\n- ❌ **Don't:** Create a new database connection per request in serverless — use connection pooling\n\n## Troubleshooting\n\n**Problem:** `db.query.tableName` is undefined\n**Solution:** Pass all schema objects (including relations) to `drizzle()`: `drizzle(client, { schema })`\n\n**Problem:** Migration conflicts after schema changes\n**Solution:** Run `npx drizzle-kit generate` to create a new migration, then `npx drizzle-kit migrate`\n\n**Problem:** Type errors on `.returning()` with MySQL\n**Solution:** MySQL does not support `RETURNING`. Use `.execute()` and read `insertId` from the result instead.\n",{"name":5,"risk":32,"source":42,"date_added":48,"description":7},"2026-03-04","main","a50a3aa6b39fb0e1b7db88bef1bfc9c93606e126","modules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fdrizzle-orm-expert",0,"https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant","https:\u002F\u002Fgithub.com\u002FSam-06060","Mobile Application Developer | Kotlin | Flutter, KMP, Swfit, Android,Swift UI | Building at Saar It Resources | Creator of Jarvis (AI Assistant)","2026-06-23 05:13:38",{"source":8,"skillName":5,"commands":58,"prompt":68,"zipAvailable":69},[59,62,65],{"tool":60,"command":61},"npx","npx skills add Sam-06060\u002Fjarvis-assistant --skill drizzle-orm-expert",{"tool":63,"command":64},"bunx","bunx skills add Sam-06060\u002Fjarvis-assistant --skill drizzle-orm-expert",{"tool":66,"command":67},"pnpm","pnpm dlx skills add Sam-06060\u002Fjarvis-assistant --skill drizzle-orm-expert","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fdrizzle-orm-expert\u002FSKILL.md",true,[71],{"path":72,"resourceType":73,"resourceTypeDesc":74,"sizeBytes":75,"sourceHtmlUrl":76},"scripts\u002Freview.py","SCRIPT","脚本",11785,"https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Fbcanfield\u002Fagentic-tech-debt\u002Fskills\u002Freview\u002Fscripts\u002Freview.py",[78,89,104,131,150,174],{"skillNo":79,"name":80,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":81,"categories":82,"keywords":86,"publishedAt":43},"01M6GDRVS6FXX3ESH0C9DW01C0","test_skill","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fscratch\u002Ftest_skill\u002FSKILL.md",[83],{"categoryNo":84,"categoryName":85,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",[87,88],"Test Skill","test",{"skillNo":90,"name":91,"nameZh":6,"description":92,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":93,"categories":94,"keywords":95,"publishedAt":43},"01M6GDRQ40HX22MA6XWC31RHHK","zustand-store-ts","Create Zustand stores following established patterns with proper TypeScript types and middleware.","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fzustand-store-ts\u002FSKILL.md",[],[96,97,98,99,100,101,102,42,103,33],"zustand store ts","zustand","store","with","types","middleware","patterns","create",{"skillNo":105,"name":106,"nameZh":6,"description":107,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":108,"categories":109,"keywords":113,"publishedAt":43},"01M6GDRKEA0WE670SPFWX5GKCN","zoom-automation","Automate Zoom meeting creation, management, recordings, webinars, and participant tracking via Rube MCP (Composio). Always search tools first for current schemas.","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fzoom-automation\u002FSKILL.md",[110],{"categoryNo":111,"categoryName":112,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[114,115,116,117,118,119,120,121,122,123,124,125,126,127,42,128,129,130],"automation","zoom automation","zoom","first","Tools","search","MCP","via","meeting","automate","critical","creation","webinars","composio","recordings","management","tracking",{"skillNo":132,"name":133,"nameZh":6,"description":134,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":135,"categories":136,"keywords":138,"publishedAt":43},"01M6GDRFS1452PC71JQ38S24HR","zoho-crm-automation","Automate Zoho CRM tasks via Rube MCP (Composio): create\u002Fupdate records, search contacts, manage leads, and convert leads. Always search tools first for current schemas.","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fzoho-crm-automation\u002FSKILL.md",[137],{"categoryNo":111,"categoryName":112,"taxonomyType":21,"taxonomyTypeDesc":22},[139,114,140,141,142,143,144,42,119,145,127,146,124,123,118,147,103,148,120,149],"crm automation","zoho crm","crm","zoho crm automation","zoho","leads","contacts","records","update","tasks","manage",{"skillNo":151,"name":152,"nameZh":6,"description":153,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":154,"categories":155,"keywords":159,"publishedAt":43},"01M6GDRCKQBAVTGHX5XBH26KPZ","zod-validation-expert","Expert in Zod — TypeScript-first schema validation. Covers parsing, custom errors, refinements, type inference, and integration with React Hook Form, Next.js, and tRPC.","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fzod-validation-expert\u002FSKILL.md",[156],{"categoryNo":157,"categoryName":158,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000009","前端开发",[30,160,161,162,163,33,32,164,165,166,167,168,99,169,170,171,172,42,38,173],"zod","zod validation expert","validation","react","parsing","errors","schema validation","react hook form","hook","trpc","form","type","next","Next.js",{"skillNo":175,"name":176,"nameZh":6,"description":177,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":178,"categories":179,"keywords":181,"publishedAt":43},"01M6GDR658B08K4MY0RWD4A6EH","zeroize-audit","Detects missing zeroization of sensitive data in source code and identifies zeroization removed by compiler optimizations, with assembly-level analysis, and control-flow verification. Use for auditing C\u002FC++\u002FRust code handling secrets, keys, passwords, or other sensitive data.","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fzeroize-audit\u002FSKILL.md",[180],{"categoryNo":111,"categoryName":112,"taxonomyType":21,"taxonomyTypeDesc":22},[182,183,184,185,186,187,188,189,42,190,191,192,193,194,195,196,197,198,199,120],"zeroize audit","audit","write","passwords","get","project","c++","activate","assembly","read","Bash","secrets","analysis","data","flow","verification","code","rust"]