Execution flow
The following page gives a simplified overview of Kysely's execution flow, from query building to querying the database. It is a nice introduction for anyone looking to understand how Kysely works under the hood. Knowing what your dependencies do and don't do is always a good idea!
This breakdown explains the journey from a type-safe method call in your application to receiving results from the database, as depicted in the diagram.
-
Immutable query building
The process starts in your
App
. You interact with theQueryBuilder
by calling its methods (selectFrom
,where
, etc.). Each call returns a newQueryBuilder
instance containing an updated, immutableQueryAST
(Abstract Syntax Tree), which is the internal representation of your SQL query. -
Initiating execution
When you chain the final
.execute()
call, theQueryBuilder
begins a multi-step execution process, commanding theQueryExecutor
to perform distinct tasks. -
Query Transformation
First, the
QueryBuilder
instructs theQueryExecutor
to process theQueryAST
. TheQueryExecutor
iterates through all registered plugins, callingtransformQuery
on each. This allows plugins to modify the query structure before compilation. The final, transformedQueryAST
is returned to theQueryBuilder
. -
Query Compilation
Next, the
QueryBuilder
tells theQueryExecutor
to compile the transformed AST. TheQueryExecutor
delegates this to theDialect
-specificQueryCompiler
. The compiler traverses the AST and produces aCompiledQuery
object (containing the final SQL string and parameters). ThisCompiledQuery
is then returned to theQueryBuilder
. -
Execution & Connection Handling
The
QueryBuilder
now asks theQueryExecutor
to execute theCompiledQuery
.- The
QueryExecutor
requests a connection from Kysely'sDriver
. - The
Driver
's job is to abstract away vendor-specific details. It communicates with the actual third-partyDatabaseDriver
— for example, thepg
ormysql2
npm package — to get a connection from its pool. - A
DatabaseConnection
object, which wraps the native connection, is returned to theQueryExecutor
.
- The
-
Database Query
The
QueryExecutor
passes theCompiledQuery
to theDatabaseConnection
object, which executes it. TheDatabaseConnection
uses the underlyingDatabaseDriver
to send the SQL and parameters to the database for execution. TheDatabaseDriver
sends the raw results back. TheDatabaseConnection
standardizes these into aQueryResult
object and returns it to theQueryExecutor
. Immediately after, the connection is released back to the pool. -
Result Transformation
The
QueryResult
is then passed through the plugin system again. TheQueryExecutor
calls thetransformResult
method on each plugin, allowing for final modifications to the results before they are returned to theApp
. -
Returning to the App
The final, transformed
QueryResult
is passed up from theQueryExecutor
to theQueryBuilder
. TheQueryBuilder
then resolves the promise from the initial.execute()
call, delivering the final, typed results to yourApp
.