Prisma Kysely Generator

3.1.0 · active · verified Wed Apr 22

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

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to configure `prisma-kysely` in your `schema.prisma` file, then initialize Kysely using the generated types for type-safe database queries. It includes an example of a type-safe SQL query for fetching a user and their post count.

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);

view raw JSON →