
Wires sqlite-vec into Room's bundled SQLite driver, optionally generating Vec companion tables, DAOs, and nearest-neighbor query operations via annotations, runtime and compiler tooling.
room-vec is a Kotlin Multiplatform helper for wiring the sqlite-vec extension into Room's bundled SQLite driver.
Add room-vec-common to your shared module to load sqlite-vec. Add room-vec-runtime
and room-vec-annotations when you want generated Vec tables and DAO operations. With a version
catalog:
[versions]
roomVec = "<version>"
[libraries]
room-vec-annotations = { module = "io.github.hub-bla:room-vec-annotations", version.ref = "roomVec" }
room-vec-common = { module = "io.github.hub-bla:room-vec-common", version.ref = "roomVec" }
room-vec-runtime = { module = "io.github.hub-bla:room-vec-runtime", version.ref = "roomVec" }
room-vec-compiler = { module = "io.github.hub-bla:room-vec-compiler", version.ref = "roomVec" }kotlin {
sourceSets {
commonMain.dependencies {
implementation(libs.room.vec.annotations)
implementation(libs.room.vec.common)
implementation(libs.room.vec.runtime)
}
}
}
dependencies {
add("kspCommonMainMetadata", libs.roomvec.compiler)
add("kspJvm", libs.room.vec.compiler)
add("kspAndroid", libs.room.vec.compiler)
add("kspIosArm64", libs.room.vec.compiler)
add("kspIosSimulatorArm64", libs.room.vec.compiler)
}
tasks.matching { it.name.startsWith("ksp") && it.name != "kspCommonMainKotlinMetadata" }.configureEach {
dependsOn("kspCommonMainKotlinMetadata")
}room-vec can be used in two ways: load sqlite-vec into Room's bundled driver with room-vec-common,
or add the annotations, runtime, and compiler to generate Vec tables and DAO operations.
If you want to write sqlite-vec SQL yourself, add withSqliteVec() only to Room's bundled SQLite driver:
import io.github.hubbla.roomvec.withSqliteVec
val db = Room.databaseBuilder<AppDatabase>(/* platform-specific arguments */)
.setDriver(BundledSQLiteDriver().withSqliteVec())
.build()Use the generated path when you want room-vec to create the sqlite-vec side tables and DAO implementation.
Configure the database builder with both withSqliteVec() hooks:
BundledSQLiteDriver().withSqliteVec() loads sqlite-vec into the driver..withSqliteVec() on RoomDatabase.Builder<AppDb> installs Vec table callbacks and the DAO factory.import io.github.hubbla.roomvec.withSqliteVec
val db = Room.databaseBuilder<AppDb>(/* platform-specific arguments */)
.setDriver(BundledSQLiteDriver().withSqliteVec())
.withSqliteVec()
.build()Declare Vec companion tables next to normal Room entities:
@Database(entities = [Document::class], version = 1)
@VecDatabase(tables = [DocumentEmbedding::class])
abstract class AppDb : RoomDatabase() {
abstract fun documentDao(): DocumentDao
fun documentEmbeddingDao(): DocumentEmbeddingDao = sqliteVecDao()
}
@Entity(tableName = "documents")
data class Document(
@PrimaryKey val id: Long,
val title: String,
val body: String,
)
@VecTable(
name = "document_vec",
owner = Document::class,
ownerPrimaryKey = "id",
)
data class DocumentEmbedding(
@VecColumn(type = VecType.FLOAT32, dimensions = 768)
val embedding: FloatArray,
)
@VecDao(table = DocumentEmbedding::class)
interface DocumentEmbeddingDao {
@VecUpsert
suspend fun upsert(documentId: Long, embedding: DocumentEmbedding)
@VecDelete
suspend fun delete(documentId: Long)
@VecNearest
suspend fun nearest(embedding: FloatArray, limit: Int): List<VecMatch<Document>>
@VecNearestIds
suspend fun nearestIds(embedding: FloatArray, limit: Int): List<VecIdMatch>
}Then use normal Room transactions together with the generated Vec DAO:
db.withWriteTransaction {
db.documentDao().insert(document)
db.documentEmbeddingDao().upsert(document.id, DocumentEmbedding(embedding))
}
val matches: List<VecMatch<Document>> =
db.documentEmbeddingDao().nearest(queryEmbedding, limit = 10)room-vec mirrors the Room APIs that make sense for sqlite-vec companion tables.
| Room API | room-vec API | Status |
|---|---|---|
@Database(entities = [...]) |
@VecDatabase(tables = [...]) |
Supported as a companion annotation on the same RoomDatabase. |
@Entity |
@VecTable(owner = Entity::class) |
Supported for Vec tables owned by Room entities. |
| Entity field | @VecColumn |
Supports one non-null FloatArray column per Vec table. |
@Dao |
@VecDao |
Supports interfaces returned from sqliteVecDao() accessors. |
@Upsert / @Delete
|
@VecUpsert / @VecDelete
|
Supported for Vec row writes and deletes. |
@Query |
@VecNearest / @VecNearestIds
|
Supported only for nearest-neighbor lookup shapes. |
RoomDatabase.Builder |
generated .withSqliteVec()
|
Supported for installing sqlite-vec table callbacks. |
Migration / AutoMigration
|
No Vec equivalent yet | Fresh databases and destructive migrations create Vec tables; existing DB migrations need manual handling. |
@Transaction, Flow, PagingSource, Rx, LiveData, relations, embedded objects, projections |
No Vec equivalent yet | To be created |
room-vec is a Kotlin Multiplatform helper for wiring the sqlite-vec extension into Room's bundled SQLite driver.
Add room-vec-common to your shared module to load sqlite-vec. Add room-vec-runtime
and room-vec-annotations when you want generated Vec tables and DAO operations. With a version
catalog:
[versions]
roomVec = "<version>"
[libraries]
room-vec-annotations = { module = "io.github.hub-bla:room-vec-annotations", version.ref = "roomVec" }
room-vec-common = { module = "io.github.hub-bla:room-vec-common", version.ref = "roomVec" }
room-vec-runtime = { module = "io.github.hub-bla:room-vec-runtime", version.ref = "roomVec" }
room-vec-compiler = { module = "io.github.hub-bla:room-vec-compiler", version.ref = "roomVec" }kotlin {
sourceSets {
commonMain.dependencies {
implementation(libs.room.vec.annotations)
implementation(libs.room.vec.common)
implementation(libs.room.vec.runtime)
}
}
}
dependencies {
add("kspCommonMainMetadata", libs.roomvec.compiler)
add("kspJvm", libs.room.vec.compiler)
add("kspAndroid", libs.room.vec.compiler)
add("kspIosArm64", libs.room.vec.compiler)
add("kspIosSimulatorArm64", libs.room.vec.compiler)
}
tasks.matching { it.name.startsWith("ksp") && it.name != "kspCommonMainKotlinMetadata" }.configureEach {
dependsOn("kspCommonMainKotlinMetadata")
}room-vec can be used in two ways: load sqlite-vec into Room's bundled driver with room-vec-common,
or add the annotations, runtime, and compiler to generate Vec tables and DAO operations.
If you want to write sqlite-vec SQL yourself, add withSqliteVec() only to Room's bundled SQLite driver:
import io.github.hubbla.roomvec.withSqliteVec
val db = Room.databaseBuilder<AppDatabase>(/* platform-specific arguments */)
.setDriver(BundledSQLiteDriver().withSqliteVec())
.build()Use the generated path when you want room-vec to create the sqlite-vec side tables and DAO implementation.
Configure the database builder with both withSqliteVec() hooks:
BundledSQLiteDriver().withSqliteVec() loads sqlite-vec into the driver..withSqliteVec() on RoomDatabase.Builder<AppDb> installs Vec table callbacks and the DAO factory.import io.github.hubbla.roomvec.withSqliteVec
val db = Room.databaseBuilder<AppDb>(/* platform-specific arguments */)
.setDriver(BundledSQLiteDriver().withSqliteVec())
.withSqliteVec()
.build()Declare Vec companion tables next to normal Room entities:
@Database(entities = [Document::class], version = 1)
@VecDatabase(tables = [DocumentEmbedding::class])
abstract class AppDb : RoomDatabase() {
abstract fun documentDao(): DocumentDao
fun documentEmbeddingDao(): DocumentEmbeddingDao = sqliteVecDao()
}
@Entity(tableName = "documents")
data class Document(
@PrimaryKey val id: Long,
val title: String,
val body: String,
)
@VecTable(
name = "document_vec",
owner = Document::class,
ownerPrimaryKey = "id",
)
data class DocumentEmbedding(
@VecColumn(type = VecType.FLOAT32, dimensions = 768)
val embedding: FloatArray,
)
@VecDao(table = DocumentEmbedding::class)
interface DocumentEmbeddingDao {
@VecUpsert
suspend fun upsert(documentId: Long, embedding: DocumentEmbedding)
@VecDelete
suspend fun delete(documentId: Long)
@VecNearest
suspend fun nearest(embedding: FloatArray, limit: Int): List<VecMatch<Document>>
@VecNearestIds
suspend fun nearestIds(embedding: FloatArray, limit: Int): List<VecIdMatch>
}Then use normal Room transactions together with the generated Vec DAO:
db.withWriteTransaction {
db.documentDao().insert(document)
db.documentEmbeddingDao().upsert(document.id, DocumentEmbedding(embedding))
}
val matches: List<VecMatch<Document>> =
db.documentEmbeddingDao().nearest(queryEmbedding, limit = 10)room-vec mirrors the Room APIs that make sense for sqlite-vec companion tables.
| Room API | room-vec API | Status |
|---|---|---|
@Database(entities = [...]) |
@VecDatabase(tables = [...]) |
Supported as a companion annotation on the same RoomDatabase. |
@Entity |
@VecTable(owner = Entity::class) |
Supported for Vec tables owned by Room entities. |
| Entity field | @VecColumn |
Supports one non-null FloatArray column per Vec table. |
@Dao |
@VecDao |
Supports interfaces returned from sqliteVecDao() accessors. |
@Upsert / @Delete
|
@VecUpsert / @VecDelete
|
Supported for Vec row writes and deletes. |
@Query |
@VecNearest / @VecNearestIds
|
Supported only for nearest-neighbor lookup shapes. |
RoomDatabase.Builder |
generated .withSqliteVec()
|
Supported for installing sqlite-vec table callbacks. |
Migration / AutoMigration
|
No Vec equivalent yet | Fresh databases and destructive migrations create Vec tables; existing DB migrations need manual handling. |
@Transaction, Flow, PagingSource, Rx, LiveData, relations, embedded objects, projections |
No Vec equivalent yet | To be created |