1
0
mirror of https://github.com/theoludwig/kysely-typegen.git synced 2026-05-22 16:23:25 +02:00
Files
kysely-typegen/README.md
T
theoludwig e11a4d2722 feat: add MySQL support
Adds `KyselyTypegenMySQLDialect`, exported from `kysely-typegen/mysql`.
2026-05-22 16:01:01 +02:00

7.7 KiB

kysely-typegen

version license

Generate Kysely type definitions from your database.

Thank you kysely-codegen for inspiration and ideas!

Why?

Why kysely-typegen if there is already kysely-codegen? Comparison:

kysely-codegen@0.20.0 kysely-typegen
Install Size 6.8 MB 5 kB
Dependencies 35 total 0 (no runtime dependencies)
Type CLI Library/Programmatic Usage
Code Size/Maintainability Heavy Lightweight/Simple and straightforward (string manipulation instead of complex AST)
Database Support PostgreSQL, MySQL, SQLite, MSSQL, LibSQL PostgreSQL, MySQL (can be easily extended to more)

kysely-typegen is a library (not a CLI), which means you are in control of where and how to run it, and is designed to be extensible, easy to add support for more database dialects.

For example: you can use Node.js with the --env-file CLI option, dotenv dependency is not required (but can be used), you are in control.

Note: kysely-typegen doesn't have the same features and customization as kysely-codegen, it has less features to keep it simple and lightweight, but can be extended to your own needs. For more details, why this project was created, and the design decisions, see: https://github.com/RobinBlomberg/kysely-codegen/issues/175.

Prerequisites

Node.js >= 24.0.0

Installation

npm install --save-dev kysely-typegen

Peer dependencies:

npm install kysely

Plus a Kysely dialect driver for your database (see Setup Kysely database below).

Usage

Setup Kysely database

Create your Kysely database instance and export a databaseTypegen for the script in the next section. The rest of the guide is dialect-agnostic: only this file changes per database.

PostgreSQL

KyselyTypegenPostgresDialect works with any Kysely PostgreSQL dialect, including the built-in PostgresDialect (using pg) and PostgresJSDialect (using postgres). The example below uses kysely-postgres-js.

npm install kysely-postgres-js postgres
// database.ts
import { Kysely } from "kysely"
import { PostgresJSDialect } from "kysely-postgres-js"
import { KyselyTypegenPostgresDialect } from "kysely-typegen/postgres"
import postgres from "postgres"

import type { DB } from "./codegen.ts"

const dialect = new PostgresJSDialect({
  postgres: postgres({
    database: process.env["DATABASE_NAME"] ?? "database",
    host: process.env["DATABASE_HOST"] ?? "localhost",
    user: process.env["DATABASE_USER"] ?? "user",
    password: process.env["DATABASE_PASSWORD"] ?? "password",
    port: Number.parseInt(process.env["DATABASE_PORT"] ?? "5432", 10),
  }),
})

export const database = new Kysely<DB>({ dialect })
export const databaseTypegen = new KyselyTypegenPostgresDialect({ database })

MySQL

npm install mysql2
// database.ts
import { Kysely, MysqlDialect } from "kysely"
import { KyselyTypegenMySQLDialect } from "kysely-typegen/mysql"
import { createPool } from "mysql2"

import type { DB } from "./codegen.ts"

const dialect = new MysqlDialect({
  pool: createPool({
    database: process.env["DATABASE_NAME"] ?? "database",
    host: process.env["DATABASE_HOST"] ?? "localhost",
    user: process.env["DATABASE_USER"] ?? "user",
    password: process.env["DATABASE_PASSWORD"] ?? "password",
    port: Number.parseInt(process.env["DATABASE_PORT"] ?? "3306", 10),
  }),
})

export const database = new Kysely<DB>({ dialect })
export const databaseTypegen = new KyselyTypegenMySQLDialect({ database })

Generate the type definitions

Create a script that uses databaseTypegen to introspect your database and write the generated types to a file. This script is the same regardless of the underlying database:

// scripts/typegen.ts
// This is an example, you can be more creative:
// time it takes to generate, number of tables/enums generated, etc.
import fs from "node:fs"
import path from "node:path"

import { database, databaseTypegen } from "./database.ts"

const result = await databaseTypegen.typegen()
const codegenContent = result.lines.join("\n")
const codegenPath = path.join(process.cwd(), "codegen.ts")
await fs.promises.writeFile(codegenPath, codegenContent, "utf-8")
await database.destroy()

Run with Node.js (using --env-file to load environment variables, no dotenv dependency required):

node --env-file=.env scripts/typegen.ts

Using the type definitions

Import DB into new Kysely<DB>, and you're done!

import { database } from "./database.ts"

const rows = await database.selectFrom("User").selectAll().execute()
//    ^ { createdAt: Date; email: string; id: number; ... }[]

Fully type-safe queries derived from your actual database schema.

Extending to other database dialects

kysely-typegen ships with KyselyTypegenPostgresDialect and KyselyTypegenMySQLDialect, but you can add support for any database by extending the abstract KyselyTypegenDialect class.

Only one thing is required:

  • scalars: a Record<string, string> mapping the database column types to TypeScript types.
import { KyselyTypegenDialect } from "kysely-typegen"

export class KyselyTypegenMSSQLDialect extends KyselyTypegenDialect {
  public override readonly scalars: Record<string, string> = {
    bigint: "Int8",
    bit: "boolean",
    char: "string",
    datetime: "Timestamp",
    decimal: "Numeric",
    int: "number",
    nvarchar: "string",
    smallint: "number",
    text: "string",
    varbinary: "Buffer",
    varchar: "string",
    // ...
  }
}

If your database supports enums, override the optional introspectEnums() hook, which returns two maps:

  • named: enum name → values (emitted as export type Name = "a" | "b").
  • inline: ${tableName}.${columnName} → values (emitted inline at the column site, for databases like MySQL where enums are anonymous per-column).
import type { IntrospectedEnums } from "kysely-typegen"

protected override async introspectEnums(): Promise<IntrospectedEnums> {
  // Query your database's information schema...
  return { named: [], inline: new Map() }
}

The base class handles introspection (via Kysely's database.introspection.getTables()), sorting, and the final type generation. Contributions of new dialects are welcome!

Contributing

Anyone can help to improve the project, submit a Feature Request, a bug report or even correct a simple spelling mistake.

The steps to contribute can be found in the CONTRIBUTING.md file.

License

MIT