Skip to main content

Overview

The CamelCasePlugin converts snake_case identifiers in the database into camelCase in the JavaScript side. This allows you to use JavaScript naming conventions in your code while maintaining SQL naming conventions in the database.

Installation

import { Kysely, CamelCasePlugin } from 'kysely'

const db = new Kysely<Database>({
  dialect,
  plugins: [new CamelCasePlugin()]
})

Usage Example

Assuming you have a table called person_table with columns first_name and last_name in the database:
import * as Sqlite from 'better-sqlite3'
import { CamelCasePlugin, Kysely, SqliteDialect } from 'kysely'

interface CamelCasedDatabase {
  userMetadata: {
    firstName: string
    lastName: string
  }
}

const db = new Kysely<CamelCasedDatabase>({
  dialect: new SqliteDialect({
    database: new Sqlite(':memory:'),
  }),
  plugins: [new CamelCasePlugin()],
})

const person = await db.selectFrom('userMetadata')
  .where('firstName', '=', 'Arnold')
  .select(['firstName', 'lastName'])
  .executeTakeFirst()

if (person) {
  console.log(person.firstName)
}
Generated SQL (SQLite):
select "first_name", "last_name" from "user_metadata" where "first_name" = ?
Everything must be defined in camelCase in the TypeScript code: table names, columns, schemas, everything. When using the CamelCasePlugin, Kysely works as if the database was defined in camelCase.

Constructor Options

interface CamelCasePluginOptions {
  upperCase?: boolean
  underscoreBeforeDigits?: boolean
  underscoreBetweenUppercaseLetters?: boolean
  maintainNestedObjectKeys?: boolean
}

upperCase

Type: boolean
Default: false
If true, camelCase is transformed into upper case SNAKE_CASE. Example:
new CamelCasePlugin({ upperCase: true })
// fooBar => FOO_BAR
// FOO_BAR => fooBar

underscoreBeforeDigits

Type: boolean
Default: false
If true, an underscore is added before each digit when converting camelCase to snake_case. Example:
new CamelCasePlugin({ underscoreBeforeDigits: true })
// foo12Bar => foo_12_bar
// foo_12_bar => foo12Bar

underscoreBetweenUppercaseLetters

Type: boolean
Default: false
If true, an underscore is added between consecutive upper case letters when converting from camelCase to snake_case. Example:
new CamelCasePlugin({ underscoreBetweenUppercaseLetters: true })
// fooBAR => foo_b_a_r
// foo_b_a_r => fooBAR

maintainNestedObjectKeys

Type: boolean
Default: false
If true, nested object’s keys will not be converted to camelCase. Example:
new CamelCasePlugin({ maintainNestedObjectKeys: true })
// Nested objects in results keep their original keys

Methods

transformQuery

transformQuery(args: PluginTransformQueryArgs): RootOperationNode
Transforms all identifiers in the query from camelCase to snake_case before execution. Source: ~/workspace/source/src/plugin/camel-case/camel-case-plugin.ts:135

transformResult

async transformResult(
  args: PluginTransformResultArgs
): Promise<QueryResult<UnknownRow>>
Transforms all keys in the result rows from snake_case to camelCase after execution. Source: ~/workspace/source/src/plugin/camel-case/camel-case-plugin.ts:139

Custom Conversion Logic

You can override the plugin’s conversion methods for custom behavior:
class MyCamelCasePlugin extends CamelCasePlugin {
  protected override snakeCase(str: string): string {
    // Custom snake_case conversion logic
    return str
  }

  protected override camelCase(str: string): string {
    // Custom camelCase conversion logic
    return str
  }
}

snakeCase

protected snakeCase(str: string): string
Converts a camelCase string to snake_case. Override this method to customize the conversion. Source: ~/workspace/source/src/plugin/camel-case/camel-case-plugin.ts:167

camelCase

protected camelCase(str: string): string
Converts a snake_case string to camelCase. Override this method to customize the conversion. Source: ~/workspace/source/src/plugin/camel-case/camel-case-plugin.ts:171

How It Works

  1. Query Transformation: When a query is built, the plugin uses a SnakeCaseTransformer to convert all identifier names from camelCase to snake_case
  2. Result Transformation: After query execution, the plugin recursively processes all result rows, converting keys from snake_case to camelCase
  3. Nested Objects: By default, nested objects and arrays are also processed recursively (unless maintainNestedObjectKeys is true)

See Also

Build docs developers (and LLMs) love