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)