Database (Room)

SkillDatabases & data

The KMP Starter Template Room database — entities, DAOs, migrations, and DB configuration in features/database. How to add tables and bump versions safely.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Database (Room) skill

What this skill tells your AI

The instructions your AI receives, as published by devatrii/kmp-starter-template in .agents/skills/kmp-starter/starter-features/database/SKILL.md and read by ahel’s review.

Room Database for local storage with multiplatform support. Entities, DAOs, migrations. Single module: features/database.

Where things live

PiecePath
KmpStarterDatabase (abstract Room db)features/database/src/commonMain/.../KmpStarterDatabase.kt
KmpStarterDatabaseMigrationsfeatures/database/src/commonMain/.../KmpStarterDatabaseMigrations.kt
getKmpDatabase (builder)features/database/src/commonMain/.../DatabaseProvider.kt
DIfeatures/database/src/commonMain/.../di/DatabaseModule.kt
KmpStarterDatabaseConstructorplatform expect/actual (Android/iOS)

1. Configure the database

KmpStarterDatabase defines the DB name and version:

@Database(
    entities = [SampleEntity::class],
    version = KmpStarterDatabase.DB_VERSION,
    exportSchema = false,
)
@ConstructedBy(KmpStarterDatabaseConstructor::class)
abstract class KmpStarterDatabase : RoomDatabase() {
    companion object {
        const val DB_NAME = "kmp_starter.db"
        const val DB_VERSION = 1   // increment on any schema change
    }
    abstract fun myDao(): MyDao
}

The builder (getKmpDatabase) wires migrations, driver, and IO context:

fun getKmpDatabase(...): KmpStarterDatabase {
    val builder = ...
    return builder
        .addMigrations(*KmpStarterDatabaseMigrations.SUPPORTED_MIGRATIONS)
        .setDriver(BundledSQLiteDriver())
        .setQueryCoroutineContext(Dispatchers.IO)
        .build()
}

2. Add a table

  1. Entity — one class per table:
@Entity
data class SampleEntity(
    @PrimaryKey(autoGenerate = true)
    val id: Int = 0,
    val value: String,
)
  1. DAO — queries, inserts, updates, deletes:
@Dao
interface MyDao {
    @Query("SELECT * FROM sample_entity")
    fun getAll(): Flow<List<SampleEntity>>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(sampleEntity: SampleEntity): Long
}
  1. Register in @Database(entities = [...]) and expose the DAO via an abstract fun.

3. Migrations

When the schema changes, add a Migration and append it to SUPPORTED_MIGRATIONS (never mutate an existing migration — add a new one):

object KmpStarterDatabaseMigrations {
    private val MIGRATION_1_2 = object : Migration(1, 2) {
        override fun migrate(connection: SQLiteConnection) {
            connection.execSQL("ALTER TABLE notes ADD COLUMN tags TEXT")
        }
    }
    val SUPPORTED_MIGRATIONS: Array<out Migration> = arrayOf(MIGRATION_1_2)
}

Then bump DB_VERSION to match the migration's end version.

Rules

  • Always increment DB_VERSION when adding columns/tables; add a matching migration.
  • Use TypeConverters for non-primitive fields (lists, custom objects).
  • Register databaseModule in InitKoin (see koin skill).

Reference

  • Docs: https://starter.atherio.dev/features/ → Database
  • Source: features/database/*

Signals

GitHub stars
162
Forks
28
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
kmp-starter-feature-database
Source
github.com/devatrii/kmp-starter-template