Prisma Kysely Generator
prisma-kysely is a Prisma generator that creates type definitions for Kysely from an existing Prisma schema. It currently stands at version 3.1.0 (published February 2026) and is actively maintained, with updates released to align with new Prisma major versions and introduce minor features. This package addresses the common developer desire to leverage Prisma's excellent schema definition and migration capabilities while utilizing Kysely for type-safe, expressive SQL query building, circumventing the limitations of the Prisma Client. It differentiates itself from alternatives like `kysely-codegen` by generating types directly from the Prisma schema file, eliminating the need for database introspection after migrations. This provides a more integrated and convenient workflow for keeping Kysely types synchronized with your database schema, ensuring full autocompletion and type safety for SQL queries. It's particularly useful for those seeking lean, serverless-ready setups without the Prisma Client's runtime footprint.
Common errors
-
Error: Generator "kysely" could not be found.
cause The `prisma-kysely` package is not installed, or the `provider` path in `schema.prisma` is incorrect.fixInstall `prisma-kysely` using your package manager (`npm install prisma-kysely` or `bun add prisma-kysely`) and verify `generator kysely { provider = "prisma-kysely" }` in your `schema.prisma` file. -
TypeError: Type 'Decimal | null' is not assignable to type 'Decimal'.
cause A custom scalar type, such as `Decimal` or `BigInt`, used in the Prisma schema is not correctly imported into the generated Kysely types file.fixIn your `schema.prisma`, add a `banner` option to the `kysely` generator to include the necessary type import. Example: `banner = "import type { Decimal } from 'decimal.js';"`. -
Error: A database URL must be provided in your Prisma configuration.
cause When upgrading to Prisma 7.0.0+, the `database url` must be moved from the `datasource` block to a `prisma.config.ts` file.fixRefer to the official Prisma 7.0.0 upgrade guide for instructions on configuring your database URL in `prisma.config.ts`. -
Error: Prisma Client is not compatible with your Prisma Schema.
cause The installed `prisma-kysely` version or the Prisma Client version (`@prisma/client`) is not compatible with your Prisma schema's version requirements, often indicated by `prisma generate` failing.fixEnsure that your `prisma-kysely` package and all `@prisma/*` packages (e.g., `@prisma/client`, `@prisma/generator-helper`) are updated to compatible versions, typically aligning with the `prisma-kysely` major version's supported Prisma version.
Warnings
- breaking Upgrading to `prisma-kysely` v3.0.0 requires Prisma 7.0.0+ and Node.js >=22.x. Additionally, Prisma 7.0.0 introduced significant changes, including requiring `database url` to be moved from the `datasource` block to a `prisma.config.ts` file.
- breaking Upgrading to `prisma-kysely` v2.0.0 moved its supported Node.js version from 16 to 24 and required Prisma 6.10.1+.
- gotcha If your Prisma schema utilizes custom scalar types (e.g., `Decimal`, `BigInt`) that are not native TypeScript types, you must use the `banner` configuration option to import their definitions into the generated Kysely type file. Failure to do so will result in TypeScript compilation errors due to unknown types.
- gotcha `prisma-kysely` requires a peer dependency on `prisma`. Mismatched versions between `prisma-kysely` and your installed `prisma` packages (`@prisma/client`, `@prisma/generator-helper`, `@prisma/internals`) can lead to generation failures or unexpected behavior.
Install
-
npm install prisma-kysely -
yarn add prisma-kysely -
pnpm add prisma-kysely
Imports
- DB
import { DB } from '../src/db/types'; // 'type' keyword is important for tree-shakingimport type { DB } from '../src/db/types'; - Kysely
import { Kysely } from 'kysely'; - generator kysely
generator client { provider = "prisma-client-js" } // Not using prisma-kyselygenerator kysely { provider = "prisma-kysely" }
Quickstart
import { Kysely, PostgresDialect } from 'kysely';
import { Pool } from 'pg';
import { config } from 'dotenv';
import type { DB } from './db/types'; // Adjust path based on your generator config
// Load environment variables from .env file
config();
// prisma/schema.prisma
/*
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator kysely {
provider = "prisma-kysely"
output = "./src/db"
fileName = "types.ts"
enumFileName = "enums.ts"
banner = """
import type { Decimal } from 'decimal.js';
"""
}
model User {
id String @id @default(uuid())
email String @unique
name String?
posts Post[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
balance Decimal? @db.Decimal(10, 2)
}
model Post {
id String @id @default(uuid())
title String
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
*/
// Configure the Kysely dialect (example for PostgreSQL)
const dialect = new PostgresDialect({
pool: new Pool({
connectionString: process.env.DATABASE_URL ?? 'postgresql://user:password@localhost:5432/mydb',
}),
});
// Instantiate Kysely with your generated database types
export const db = new Kysely<DB>({
dialect,
});
// Example usage: Fetch a user and their post count
async function getUserWithPostCount(userId: string) {
try {
const userWithPosts = await db
.selectFrom('User')
.selectAll('User')
.leftJoin('Post', 'Post.authorId', 'User.id')
.where('User.id', '=', userId)
.select((eb) => eb.fn.count('Post.id').as('postCount'))
.executeTakeFirst();
if (userWithPosts) {
console.log(`User: ${userWithPosts.name}, Email: ${userWithPosts.email}, Posts: ${userWithPosts.postCount}`);
return userWithPosts;
} else {
console.log(`User with ID ${userId} not found.`);
return null;
}
} catch (error) {
console.error('Error fetching user with post count:', error);
throw error;
}
}
// To run this example, you'd need a DATABASE_URL env var and 'pg', 'dotenv' packages.
// Example call (replace with an actual user ID from your database):
// getUserWithPostCount('some-actual-user-id').catch(console.error);