We recently migrated an internal application from Sequelize to Prisma. I love the way we can observe our entire database schema with a single file and generate actual sql files for migrations. Recently I figured out a simple way to import Prisma types on the client-side. We are using Turbo repo and one of our devs ended up using a generator with the Prisma schema to create types for the front-end. I don't like redundancy so I did some digging. Here's what I did to solve the issue.
root directory snapshot
pnpm-workspace.yaml
packages: - "client" - "server" - "prisma" - "packages/*"
package.json
{ "name": "tutorial", "private": true, "version": "0.0.0", "scripts": { "dev": "turbo run dev --parallel", "dev:client": "turbo run dev --filter=!server --parallel", "build": "turbo run build", "build:client": "turbo run build --filter=!server", "start": "turbo run start" }, "devDependencies": { "turbo": "^1.11.1" } }
turbo.json
{ "$schema": "https://turbo.build/schema.json", "pipeline": { "dev": { "dependsOn": ["db:generate"], "cache": false }, "build": { "dependsOn": ["db:generate"], "outputs": ["dist/**"], "cache": false }, "start": { "dependsOn": ["^build"], "cache": false }, "db:generate": { "cache": false } } }
prisma directory snapshot
prisma/package.json
{ "name": "prisma", "version": "0.0.0", "private": true, "scripts": { "db:generate": "prisma generate", "db:push": "prisma db push", "db:seed": "ts-node seed.ts" }, "dependencies": { "@prisma/client": "5.7.1", "prisma": "^5.5.2", "ts-node": "^10.9.1" } }
prisma/index.ts
export * from '@prisma/client';
client/package.json ➡️ devDependencies
... "prisma": "workspace:*", ...
client/tsconfig.json
{ "extends": "tsconfig/vue.json", "compilerOptions": { "baseUrl": ".", "paths": { "@/*": ["src/*"], "prisma": ["../prisma/node_modules/@prisma/client/*"] }, "types": [ "../prisma/node_modules/@prisma/client/index.d.ts", "../prisma/node_modules/@prisma/client/runtime/library.d.ts" ] }, "include": ["src"], "exclude": ["dist", "node_modules"] }
server/package.json ➡️ dependencies
... "prisma": "workspace:*", ...
server/tsconfig.json
{ "extends": "tsconfig/node.json", "compilerOptions": { "baseUrl": ".", "strict": false, "paths": { "@/*": ["src/*"], "prisma": ["../prisma/node_modules/@prisma/client/*"] }, "types": [ "../prisma/node_modules/@prisma/client/index.d.ts", "../prisma/node_modules/@prisma/client/runtime/library.d.ts" ] }, "include": ["src"], "exclude": ["dist", "node_modules"] }
On the client we can import Prisma types like this:
import type { User } from 'prisma';
Hover over User
to verify that the types will resolve correctly.
On the server side we can create a new Prisma client instance like this:
import { PrismaClient } from 'prisma'; export const prisma = new PrismaClient();
Hover over PrismaClient()
to verify that it will resolve correctly.
Prisma doesn't include relationships with the generate types so we have to do this by hand. Here's a quick example.
prisma/index.ts
export * from '@prisma/client'; import type { User as $User, Role } from '@prisma/client'; export type User = { role: Role; } & $User;
Hover over User
to verify that Role
will be included in the type.
I imagine this will be helpful to many as I haven't found a direct answer for this elsewhere. If you questions or comments please feel free to share!
Top comments (0)