This library provides an API similar to drizzle's relations so that kysely can be used as an ORM.
interface Database {
users: { id: number; name: string };
posts: { id: number; user_id: number; title: string };
profiles: { id: number; user_id: number; bio: string };
tags: { id: number; name: string };
post_tags: { post_id: number; tag_id: number };
}
// Create a relation builder for your database schema
const relations = createRelationsBuilder<Database>();
// Define reusable relations for the users table
const userRelations = relations('users', ({ hasOne, hasMany }) => ({
// hasOne: nullable one-to-one relation
profile: hasOne('profile', {
target: 'profiles', // target table
column: 'users.id', // source column
reference: 'profiles.user_id' // foreign key
}),
// hasMany: one-to-many with optional query customization
americanPosts: hasMany('americanPosts', {
target: 'posts',
column: 'users.id',
reference: 'posts.user_id'
}, (qb) => qb.where('title', 'like', 'America%'))
}));
// Define relations for posts table
const postRelations = relations('posts', ({ hasManyThrough }) => ({
// hasManyThrough: many-to-many via junction table
tags: hasManyThrough('tags', {
target: 'tags',
column: 'posts.id',
reference: 'tags.id',
through: 'post_tags',
throughSourceKey: 'post_tags.post_id',
throughTargetKey: 'post_tags.tag_id'
})
}));
// Use relations in queries - pass a query builder to specify selected fields
// Returns: Promise<{ id: number; profile: { id: number; bio: string } | null }[]>
db.selectFrom('users')
.select(eb => [
'id',
userRelations.profile(qb => qb.select(['id', 'bio']))
])
.execute();
// Nested relations: select posts with their tags
// Returns: Promise<{ id: number; posts: { title: string; tags: { name: string }[] }[] }[]>
db.selectFrom('users')
.select(eb => [
'id',
userRelations.americanPosts(qb => qb.select([
'title',
postRelations.tags(tagQb => tagQb.select('name'))
]))
])
.execute();
// Type error: userRelations only works with 'users' table
db.selectFrom('profiles')
.select(eb => userRelations.profile(qb => qb.select('id')))
.execute();You can download the helpers into your project by running the following command:
mkdir -p relations-builder \
&& curl -o relations-builder/index.js https://gist.githubusercontent.com/alexander-azizi-martin/4d81db00708c502776618e4e756b747c/raw/51da78dee1086467a475c2a8f38490c42cecf8f1/relations-builder.js \
&& curl -o relations-builder/index.d.ts https://gist.githubusercontent.com/alexander-azizi-martin/4d81db00708c502776618e4e756b747c/raw/51da78dee1086467a475c2a8f38490c42cecf8f1/relations-builder.d.ts