A real solution for client-side Prisma types
Tags: prisma, frontend, backend, javascript
Published: 2023-12-27 15:58:36

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**
 
![VS Code project directory](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zqa0rvys8zyc9fbhlizr.png)

**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**

![VS Code prisma directory](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2nwg9pkhkrcy8whzhann.png)

**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.

![Prisma User type import](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9bnr9fhpo65tp3821hur.png)


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.

![PrismaClient import](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kv8uldiqilni6i8l1f25.png)

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.

![Prisma User type with Role](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kacw7kr0oeh7n32zjylf.png)

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!