Skip to main content
Kysely doesn’t have built-in functions for every SQL operation, but it provides the tools to create your own composable, type-safe helpers.

The problem

Let’s say you want to write this query:
Kysely doesn’t have a built-in upper function. You have several options:
Each option has tradeoffs in readability and type safety.

Creating helper functions

Fortunately, Kysely allows you to create reusable, type-safe helpers:
Now our query is much cleaner:

The recipe

The pattern for helper functions is simple:
1

Accept expressions as input

Take inputs as Expression<T> where T is the type of the expression.
  • upper takes Expression<string> (transforms strings)
  • round would take Expression<number> (only rounds numbers)
2

Return an expression

Use the inputs to create an output that’s also an Expression. Everything in Kysely is an expression:
  • Expression builder outputs
  • sql template tag results
  • SelectQueryBuilder instances
  • Pretty much everything else
See the expressions recipe to learn more about how expressions work.

Composing helpers

Since everything is an expression, helpers are composable:

Using helpers anywhere

Helpers work in any part of a query:
When using a helper in select, you must always provide an explicit name using the as method.

Helpers using ExpressionBuilder

You can create helpers that use the expression builder instead of raw SQL:
Usage:
This generates a single query with a subquery:

Boolean expressions

You can create helpers that return boolean expressions:
When using eb as a function like eb(left, operator, right), it creates a binary expression. All binary expressions with comparison operators are Expression<SqlBool>. You can return any Expression<SqlBool> from the callback.

Handling nullable expressions

To support nullable expressions, use conditional types:

Converting subquery types

SQL allows single-column subqueries to be used as scalars. Use $asScalar() to convert the type:
$asScalar() has no effect on the generated SQL — it’s purely a type-level helper.

Key takeaways

Everything is an expression

All Kysely constructs are composable expressions

Type-safe inputs

Use Expression<T> for inputs to maintain type safety

Reusable and composable

Helpers can be used together and anywhere in queries

No runtime overhead

Helpers are just TypeScript — they compile away