bitovi/ai-enablement-prompts/cross-package-types

Claude Code and agent skill by bitovi/ai-enablement-prompts

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Type flow patterns for tRPC + Prisma monorepos. Covers AppRouter type inference across shared, server, and client packages. Use when setting up types, fixing type errors across packages, or understanding the type chain.

Install

npx vskill@latest install bitovi/ai-enablement-prompts/cross-package-types

SKILL.md

Skill: Cross-Package Types (tRPC + Prisma)

Defines how TypeScript types flow through a monorepo with tRPC and Prisma.

Type Flow

Prisma Schema → Prisma Client Types → Zod Schemas → tRPC Routers → Client Type Inference
Package Responsibilities
PackageOwnsExports
sharedZod schemas, enums, constantsSchemas for both server and client
servertRPC routers, Prisma clientAppRouter type
clientReact components, tRPC hooksConsumes AppRouter type

Key Principles

  1. Prisma is the single source of truth — all types derive from the Prisma schema
  2. Zod schemas derive from Prisma types — use .pick(), .omit(), .extend() on base schemas
  3. AppRouter types flow from server to client — never import server code in client
  4. No circular dependencies — shared → server → client (one direction only)

Shared Package

The shared package has two entry points:

typescript
// package.json
{
"exports": {
"./server": "./src/server/index.ts", // Server-only: Prisma, DB utils
".": "./src/index.ts" // Browser-safe: Zod schemas, types, constants
}
}
Schema Derivation
typescript
// shared/src/schemas/user.ts
import { z } from 'zod';
// Base schema matching Prisma model
export const UserSchema = z.object({
id: z.string().uuid(),
email: z.string().email(),
name: z.string().min(1),
role: z.enum(['ADMIN', 'USER', 'VIEWER']),
createdAt: z.date(),
updatedAt: z.date(),
});
// Auto-managed fields
const PRISMA_AUTO_FIELDS = ['id', 'createdAt', 'updatedAt'] as const;
// Input schema (for create)
export const CreateUserSchema = UserSchema.omit(
Object.fromEntries(PRISMA_AUTO_FIELDS.map(f => [f, true])) as Record<string, true>
);
// Update schema (partial, without auto fields)
export const UpdateUserSchema = CreateUserSchema.partial();
// Form schema (client-friendly, no server-only fields)
export const UserFormSchema = UserSchema.pick({
email: true,
name: true,
role: true,
});
export type User = z.infer<typeof UserSchema>;
export type CreateUserInput = z.infer<typeof CreateUserSchema>;
export type UpdateUserInput = z.infer<typeof UpdateUserSchema>;

Server Package

tRPC Router Pattern
typescript
// server/src/routers/user.ts
import { router, protectedProcedure } from '../trpc';
import { CreateUserSchema, UpdateUserSchema } from '@myapp/shared';
import { prisma } from '@myapp/shared/server';
export const userRouter = router({
list: protectedProcedure.query(async () => {
return prisma.user.findMany();
}),
create: protectedProcedure
.input(CreateUserSchema)
.mutation(async ({ input }) => {
return prisma.user.create({ data: input });
}),
update: protectedProcedure
.input(z.object({ id: z.string().uuid(), data: UpdateUserSchema }))
.mutation(async ({ input }) => {
return prisma.user.update({ where: { id: input.id }, data: input.data });
}),
});
AppRouter Export
typescript
// server/src/routers/index.ts
import { router } from '../trpc';
import { userRouter } from './user';
export const appRouter = router({
user: userRouter,
});
export type AppRouter = typeof appRouter;

Client Package

Type-Safe tRPC Client
typescript
// client/src/utils/trpc.ts
import { createTRPCReact } from '@trpc/react-query';
import type { AppRouter } from '@myapp/server';
export const trpc = createTRPCReact<AppRouter>();
Usage in Components
typescript
// client/src/components/UserList.tsx
import { trpc } from '../utils/trpc';
export function UserList() {
const { data: users } = trpc.user.list.useQuery();
// `users` is fully typed as User[] automatically
}

Common Mistakes

  • ❌ Importing server code in client (breaks browser bundle)
  • ❌ Defining types manually instead of deriving from Prisma/Zod
  • ❌ Circular imports between packages
  • ❌ Using any to silence cross-package type errors
  • ✅ Use type imports: import type { AppRouter } from '@myapp/server'
  • ✅ Derive all schemas from Prisma base types
  • ✅ Use shared package for browser-safe code

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

7-day trend score
0

Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/bitovi/ai-enablement-prompts/cross-package-types/badge)](https://verified-skill.com/skills/bitovi/ai-enablement-prompts/cross-package-types)

Something wrong with this skill or its page? Tell us.