Command-line tool for Kysely, Knex-compatible, works in Node.js, Deno, Bun, etc.
316
stars
455
commits
TypeScript
primary language
Aug 6, 2026
updated
kysely-ctl is the official command-line tool for Kysely.
We strive to make it TypeScript-first, cross-platform
(macOS, Linux, and Windows),
cross-runtime (Node.js, Bun, and Deno),
and cross-module system (ESM
and CommonJS) compatible.
We also aim to have feature parity with Knex.js's CLI.
kysely-ctl requires kysely >= 0.18.1 to be installed in your project/s.
kysely-ctl will be available as kysely in your terminal,
anywhere.npm i -g kysely-ctl
or:
pnpm add -g kysely-ctl
bun add -g kysely-ctl
deno install -g -f npm:kysely-ctl@latest
kysely-ctl in your project as a dev dependency,
which will make it available as kysely in your project's package.json:npm i -D kysely-ctl
or:
yarn add -D kysely-ctl
or:
pnpm add -D kysely-ctl
bun add -D kysely-ctl
deno add -D npm:kysely-ctl
kysely.config.ts file is required, in the project root OR .config
folder. Run kysely init in your terminal to create one.import { defineConfig } from "kysely-ctl";
export default defineConfig({
destroyOnExit, // optional. dictates whether the (resolved) `kysely` instance should be destroyed when a command is finished executing. default is `true`.
dialect, // a `Kysely` dialect instance OR the name of an underlying driver library (e.g. `'pg'`).
dialectConfig, // optional. when `dialect` is the name of an underlying driver library, `dialectConfig` is the options passed to the Kysely dialect that matches that library.
migrations: { // optional.
allowJS, // optional. controls whether `.js`, `.cjs` or `.mjs` migrations are allowed. default is `false`.
getMigrationPrefix, // optional. a function that returns a migration prefix. affects `migrate make` command. default is `() => ${Date.now()}_`.
migrationFolder, // optional. path to where migration files are located. default is a folder named "migrations" next to the config file/folder.
migrator, // optional. a `Kysely` migrator instance factory of shape `(db: Kysely<any>) => Migrator | Promise<Migrator>`. default is `Kysely`'s `Migrator`.
provider, // optional. a `Kysely` migration provider instance. default is `kysely-ctl`'s `TSFileMigrationProvider`.
},
plugins, // optional. `Kysely` plugins list. default is `[]`.
seeds: { // optional.
allowJS, // optional. controls whether `.js`, `.cjs` or `.mjs` seeds are allowed. default is `false`.
getSeedPrefix, // optional. a function that returns a seed prefix. affects `seed make` command. default is `() => ${Date.now()}_`.
provider, // optional. a seed provider instance. default is `kysely-ctl`'s `FileSeedProvider`.
seeder, // optional. a seeder instance factory of shape `(db: Kysely<any>) => Seeder | Promise<Seeder>`. default is `kysely-ctl`'s `Seeder`.
seedFolder, // optional. path to where seed files are located. default is a folder named "seeds" next to the config file/folder.
}
});
You can pass a Kysely instance, instead of dialect, dialectConfig & plugins:
import { defineConfig } from "kysely-ctl";
import { kysely } from 'path/to/kysely/instance';
export default defineConfig({
destroyOnExit, // optional. dictates whether the `kysely` instance should be destroyed when a command is finished executing. default is `true`.
// ...
kysely,
// ...
});
To use Knex's timestamp prefixes:
import { defineConfig, getKnexTimestampPrefix } from "kysely-ctl";
export default defineConfig({
// ...
migrations: {
// ...
getMigrationPrefix: getKnexTimestampPrefix,
// ...
},
// ...
});
See c12 docs and the following example.
For more information run kysely -h in your terminal.
migrate module mirrors Knex.js CLI's module of the
same name.knex migrate:<command>
Can now be called as either:
kysely migrate:<command>
or
kysely migrate <command>
[!NOTE]
rollbackwithout--allflag is not supported, as Kysely doesn't keep track of "migration batches".
seed module mirrors Knex.js CLI's module of the same
name.knex seed:<command>
Can now be called as either:
kysely seed:<command>
or
kysely seed <command>
[!NOTE] We also provide
kysely seed list, which is not part of Knex.js CLI.
sql module allows you to run SQL queries directly from the command line using the kysely instance.Single-query:
kysely sql "select 1"
or interactive mode:
kysely sql -f json
✔ sqlite ❯
select 1;
{
"rows": [
{
"1": 1
}
]
}
❯ sqlite ❯
exit
acro5piano who built kysely-migration-cli and inspired this project.
UnJS's amazing tools that help power this project.
Knex.js team for paving the way.
TypeScript
96.7%
JavaScript
3.3%
Command-line tool for Kysely, Knex-compatible, works in Node.js, Deno, Bun, etc.
316
stars
455
commits
TypeScript
primary language
Aug 6, 2026
updated
kysely-ctl is the official command-line tool for Kysely.
We strive to make it TypeScript-first, cross-platform
(macOS, Linux, and Windows),
cross-runtime (Node.js, Bun, and Deno),
and cross-module system (ESM
and CommonJS) compatible.
We also aim to have feature parity with Knex.js's CLI.
kysely-ctl requires kysely >= 0.18.1 to be installed in your project/s.
kysely-ctl will be available as kysely in your terminal,
anywhere.npm i -g kysely-ctl
or:
pnpm add -g kysely-ctl
bun add -g kysely-ctl
deno install -g -f npm:kysely-ctl@latest
kysely-ctl in your project as a dev dependency,
which will make it available as kysely in your project's package.json:npm i -D kysely-ctl
or:
yarn add -D kysely-ctl
or:
pnpm add -D kysely-ctl
bun add -D kysely-ctl
deno add -D npm:kysely-ctl
kysely.config.ts file is required, in the project root OR .config
folder. Run kysely init in your terminal to create one.import { defineConfig } from "kysely-ctl";
export default defineConfig({
destroyOnExit, // optional. dictates whether the (resolved) `kysely` instance should be destroyed when a command is finished executing. default is `true`.
dialect, // a `Kysely` dialect instance OR the name of an underlying driver library (e.g. `'pg'`).
dialectConfig, // optional. when `dialect` is the name of an underlying driver library, `dialectConfig` is the options passed to the Kysely dialect that matches that library.
migrations: { // optional.
allowJS, // optional. controls whether `.js`, `.cjs` or `.mjs` migrations are allowed. default is `false`.
getMigrationPrefix, // optional. a function that returns a migration prefix. affects `migrate make` command. default is `() => ${Date.now()}_`.
migrationFolder, // optional. path to where migration files are located. default is a folder named "migrations" next to the config file/folder.
migrator, // optional. a `Kysely` migrator instance factory of shape `(db: Kysely<any>) => Migrator | Promise<Migrator>`. default is `Kysely`'s `Migrator`.
provider, // optional. a `Kysely` migration provider instance. default is `kysely-ctl`'s `TSFileMigrationProvider`.
},
plugins, // optional. `Kysely` plugins list. default is `[]`.
seeds: { // optional.
allowJS, // optional. controls whether `.js`, `.cjs` or `.mjs` seeds are allowed. default is `false`.
getSeedPrefix, // optional. a function that returns a seed prefix. affects `seed make` command. default is `() => ${Date.now()}_`.
provider, // optional. a seed provider instance. default is `kysely-ctl`'s `FileSeedProvider`.
seeder, // optional. a seeder instance factory of shape `(db: Kysely<any>) => Seeder | Promise<Seeder>`. default is `kysely-ctl`'s `Seeder`.
seedFolder, // optional. path to where seed files are located. default is a folder named "seeds" next to the config file/folder.
}
});
You can pass a Kysely instance, instead of dialect, dialectConfig & plugins:
import { defineConfig } from "kysely-ctl";
import { kysely } from 'path/to/kysely/instance';
export default defineConfig({
destroyOnExit, // optional. dictates whether the `kysely` instance should be destroyed when a command is finished executing. default is `true`.
// ...
kysely,
// ...
});
To use Knex's timestamp prefixes:
import { defineConfig, getKnexTimestampPrefix } from "kysely-ctl";
export default defineConfig({
// ...
migrations: {
// ...
getMigrationPrefix: getKnexTimestampPrefix,
// ...
},
// ...
});
See c12 docs and the following example.
For more information run kysely -h in your terminal.
migrate module mirrors Knex.js CLI's module of the
same name.knex migrate:<command>
Can now be called as either:
kysely migrate:<command>
or
kysely migrate <command>
[!NOTE]
rollbackwithout--allflag is not supported, as Kysely doesn't keep track of "migration batches".
seed module mirrors Knex.js CLI's module of the same
name.knex seed:<command>
Can now be called as either:
kysely seed:<command>
or
kysely seed <command>
[!NOTE] We also provide
kysely seed list, which is not part of Knex.js CLI.
sql module allows you to run SQL queries directly from the command line using the kysely instance.Single-query:
kysely sql "select 1"
or interactive mode:
kysely sql -f json
✔ sqlite ❯
select 1;
{
"rows": [
{
"1": 1
}
]
}
❯ sqlite ❯
exit
acro5piano who built kysely-migration-cli and inspired this project.
UnJS's amazing tools that help power this project.
Knex.js team for paving the way.
TypeScript
96.7%
JavaScript
3.3%