kysely-codegen
generates Kysely type definitions from your database. That's it.
- Installation
- Generating type definitions
- Using the type definitions
- CLI arguments
- Configuration file
- Issue funding
npm install --save-dev kysely-codegen
You will also need to install Kysely with your driver of choice:
# PostgreSQL
npm install kysely pg
# MySQL
npm install kysely mysql2
# SQLite
npm install kysely better-sqlite3
# MSSQL
npm install kysely tedious tarn @tediousjs/connection-string
# LibSQL
npm install @libsql/kysely-libsql
The most convenient way to get started is to create an .env
file with your database connection string:
# PostgreSQL
DATABASE_URL=postgres://username:[email protected]/database
# MySQL
DATABASE_URL=mysql://username:[email protected]/database
# SQLite
DATABASE_URL=C:/Program Files/sqlite3/db
# MSSQL
DATABASE_URL=Server=mssql;Database=database;User Id=user;Password=password
# LibSQL
DATABASE_URL=libsql://token@host:port/database
If your URL contains a password with special characters, those characters may need to be percent-encoded.
If you are using PlanetScale, make sure your URL contains this SSL query string parameter:
ssl={"rejectUnauthorized":true}
Then run the following command, or add it to the scripts section in your package.json file:
kysely-codegen
This command will generate a .d.ts
file from your database, for example:
import { ColumnType } from 'kysely';
export type Generated<T> = T extends ColumnType<infer S, infer I, infer U>
? ColumnType<S, I | undefined, U>
: ColumnType<T, T | undefined, T>;
export type Timestamp = ColumnType<Date, Date | string, Date | string>;
export interface Company {
id: Generated<number>;
name: string;
}
export interface User {
company_id: number | null;
created_at: Generated<Timestamp>;
email: string;
id: Generated<number>;
is_active: boolean;
name: string;
updated_at: Timestamp;
}
export interface DB {
company: Company;
user: User;
}
To specify a different output file:
kysely-codegen --out-file ./src/db/db.d.ts
Import DB
into new Kysely<DB>
, and you're done!
import { Kysely, PostgresDialect } from 'kysely';
import { DB } from 'kysely-codegen';
import { Pool } from 'pg';
const db = new Kysely<DB>({
dialect: new PostgresDialect({
pool: new Pool({
connectionString: process.env.DATABASE_URL,
}),
}),
});
const rows = await db.selectFrom('users').selectAll().execute();
// ^ { created_at: Date; email: string; id: number; ... }[]
If you need to use the generated types in e.g. function parameters and type definitions, you may need to use the Kysely Insertable
, Selectable
, Updateable
types. Note that you don't need to explicitly annotate query return values, as it's recommended to let Kysely infer the types for you.
import { Insertable, Updateable } from 'kysely';
import { DB } from 'kysely-codegen';
import { db } from './db';
async function insertUser(user: Insertable<User>) {
return await db
.insertInto('users')
.values(user)
.returningAll()
.executeTakeFirstOrThrow();
// ^ Selectable<User>
}
async function updateUser(id: number, user: Updateable<User>) {
return await db
.updateTable('users')
.set(user)
.where('id', '=', id)
.returning(['email', 'id'])
.executeTakeFirstOrThrow();
// ^ { email: string; id: number; }
}
Read the Kysely documentation for more information.
Use the Kysely CamelCasePlugin for generated table column names.
Example:
export interface User {
companyId: number | null;
createdAt: Generated<Timestamp>;
email: string;
id: Generated<number>;
isActive: boolean;
name: string;
updatedAt: Timestamp;
}
Specify which parser to use for PostgreSQL date values. (values: string
/timestamp
, default: timestamp
)
Set the default schema(s) for the database connection.
Multiple schemas can be specified:
kysely-codegen --default-schema=public --default-schema=hidden
Set the SQL dialect. (values: postgres
/mysql
/sqlite
/mssql
/libsql
/bun-sqlite
/kysely-bun-sqlite
/worker-bun-sqlite
)
Specify the path to an environment file to use.
Print all command line options.
You can choose which tables should be included during code generation by providing a glob pattern to the --include-pattern
and --exclude-pattern
flags. We use micromatch under the hood, which provides advanced glob support. For instance, if you only want to include your public tables:
kysely-codegen --include-pattern="public.*"
You can also include only certain tables within a schema:
kysely-codegen --include-pattern="public.+(user|post)"
Or exclude an entire class of tables:
kysely-codegen --exclude-pattern="documents.*"
Set the terminal log level. (values: debug
/info
/warn
/error
/silent
, default: warn
)
Skip generating types for PostgreSQL domains. (default: false
)
Specify which parser to use for PostgreSQL numeric values. (values: string
/number
/number-or-string
, default: string
)
Specify type overrides for specific table columns in JSON format.
Example:
kysely-codegen --overrides='{"columns":{"table_name.column_name":"{foo:\"bar\"}"}}'
Set the file build path. (default: ./node_modules/kysely-codegen/dist/db.d.ts
)
Include partitions of PostgreSQL tables in the generated code.
Print the generated output to the terminal instead of a file.
The PostgreSQL --runtime-enums
option generates runtime enums instead of string unions. You can optionally specify which naming convention to use for runtime enum keys. (values: [pascal-case
, screaming-snake-case
], default: screaming-snake-case
)
Examples:
--runtime-enums=false
export type Status = 'CONFIRMED' | 'UNCONFIRMED';
--runtime-enums
or --runtime-enums=screaming-snake-case
export enum Status {
CONFIRMED = 'CONFIRMED',
UNCONFIRMED = 'UNCONFIRMED',
}
--runtime-enums=pascal-case
export enum Status {
Confirmed = 'CONFIRMED',
Unconfirmed = 'UNCONFIRMED',
}
Singularize generated type aliases, e.g. as BlogPost
instead of BlogPosts
. The codegen uses the pluralize package for singularization.
You can specify custom singularization rules in the configuration file.
Generate code using the TypeScript 3.8+ import type
syntax. (default: true
)
Set the database connection string URL. This may point to an environment variable. (default: env(DATABASE_URL)
)
Verify that the generated types are up-to-date. (default: false
)
All codegen options can also be configured in a .kysely-codegenrc.json
(or .js
, .ts
, .yaml
etc.) file or the kysely-codegen
property in package.json
. See Cosmiconfig for all available configuration file formats.
The default configuration:
{
"camelCase": false,
"dateParser": "timestamp",
"defaultSchemas": [], // ["public"] for PostgreSQL.
"dialect": null,
"domains": true,
"envFile": null,
"excludePattern": null,
"includePattern": null,
"logLevel": "warn",
"numericParser": "string",
"outFile": "./node_modules/kysely-codegen/dist/db.d.ts",
"overrides": {},
"partitions": false,
"print": false,
"runtimeEnums": false,
"singularize": false,
"typeOnlyImports": true,
"url": "env(DATABASE_URL)",
"verify": false
}
The configuration object adds support for more advanced options:
{
"camelCase": true,
"overrides": {
"columns": {
"users.settings": "{ theme: 'dark' }"
}
},
"singularize": {
"/^(.*?)s?$/": "$1_model",
"/(bacch)(?:us|i)$/i": "$1us"
}
}
The generated output:
export interface UserModel {
settings: { theme: 'dark' };
}
// ...
export interface DB {
bacchi: Bacchus;
users: UserModel;
}
We use Polar.sh to upvote and promote specific features that you would like to see implemented. Check the backlog and help out: