diff --git a/README.md b/README.md
index 2643bd8..5a1ee8a 100644
--- a/README.md
+++ b/README.md
@@ -17,10 +17,18 @@ The project is designed as:
     - [ ] A Merchant App to sell items
     - [ ] Admin App to check on status of everything
 
--
+
+### [Tech Stack 🛠]
+- [ ] Kotlin
+- [ ] Jetpack Compose
+
+*use JVM 21*
+
+### [Features 🚀]
+
 
 
 ## Contributing
- Hop on here for a chat and ask questions. NO DMs please :)
+ Create an [issue here](https://github.com/droidconKE/doko/issues) and ask questions. NO DMs please :)
 
 
diff --git a/buildLogic/convention/build.gradle.kts b/buildLogic/convention/build.gradle.kts
new file mode 100644
index 0000000..d6ffbf8
--- /dev/null
+++ b/buildLogic/convention/build.gradle.kts
@@ -0,0 +1,86 @@
+import org.jetbrains.kotlin.gradle.dsl.JvmTarget
+
+plugins {
+    `kotlin-dsl`
+}
+
+group = "com.droidconke.doko.buildlogic"
+
+java {
+    sourceCompatibility = JavaVersion.VERSION_21
+    targetCompatibility = JavaVersion.VERSION_21
+}
+
+kotlin {
+    compilerOptions {
+        jvmTarget = JvmTarget.JVM_21
+    }
+}
+
+dependencies {
+    compileOnly(libs.android.gradlePlugin)
+    compileOnly(libs.android.tools.common)
+    compileOnly(libs.compose.gradlePlugin)
+    compileOnly(libs.firebase.crashlytics.gradlePlugin)
+    compileOnly(libs.firebase.performance.gradlePlugin)
+    compileOnly(libs.kotlin.gradlePlugin)
+    compileOnly(libs.ksp.gradlePlugin)
+    compileOnly(libs.room.gradlePlugin)
+    implementation(libs.truth)
+}
+
+tasks {
+    validatePlugins {
+        enableStricterValidation = true
+        failOnWarning = true
+    }
+}
+
+gradlePlugin {
+    plugins {
+        register("androidApplicationCompose") {
+            id = "doko.android.application.compose"
+            implementationClass = "AndroidApplicationComposeConventionPlugin"
+        }
+        register("androidApplication") {
+            id = "doko.android.application"
+            implementationClass = "AndroidApplicationConventionPlugin"
+        }
+        register("androidLibraryCompose") {
+            id = "doko.android.library.compose"
+            implementationClass = "AndroidLibraryComposeConventionPlugin"
+        }
+        register("androidLibrary") {
+            id = "doko.android.library"
+            implementationClass = "AndroidLibraryConventionPlugin"
+        }
+        register("androidFeature") {
+            id = "doko.android.feature"
+            implementationClass = "AndroidFeatureConventionPlugin"
+        }
+        register("androidTest") {
+            id = "doko.android.test"
+            implementationClass = "AndroidTestConventionPlugin"
+        }
+        register("hilt") {
+            id = "doko.hilt"
+            implementationClass = "HiltConventionPlugin"
+        }
+        register("androidRoom") {
+            id = "doko.android.room"
+            implementationClass = "AndroidRoomConventionPlugin"
+        }
+        register("androidFirebase") {
+            id = "doko.android.application.firebase"
+            implementationClass = "AndroidApplicationFirebaseConventionPlugin"
+        }
+        register("androidLint") {
+            id = "doko.android.lint"
+            implementationClass = "AndroidLintConventionPlugin"
+        }
+        register("jvmLibrary") {
+            id = "doko.jvm.library"
+            implementationClass = "JvmLibraryConventionPlugin"
+        }
+    }
+}
diff --git a/buildLogic/convention/src/main/kotlin/AndroidApplicationComposeConventionPlugin.kt b/buildLogic/convention/src/main/kotlin/AndroidApplicationComposeConventionPlugin.kt
new file mode 100644
index 0000000..197199f
--- /dev/null
+++ b/buildLogic/convention/src/main/kotlin/AndroidApplicationComposeConventionPlugin.kt
@@ -0,0 +1,19 @@
+import com.android.build.api.dsl.ApplicationExtension
+import com.droidconke.doko.configureAndroidCompose
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.apply
+import org.gradle.kotlin.dsl.getByType
+
+class AndroidApplicationComposeConventionPlugin : Plugin<Project> {
+    override fun apply(target: Project) {
+        with(target) {
+            apply(plugin = "com.android.application")
+            apply(plugin = "org.jetbrains.kotlin.plugin.compose")
+            apply(plugin = "org.jetbrains.kotlin.android")
+
+            val extension = extensions.getByType<ApplicationExtension>()
+            configureAndroidCompose(extension)
+        }
+    }
+}
diff --git a/buildLogic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt b/buildLogic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt
new file mode 100644
index 0000000..351d78c
--- /dev/null
+++ b/buildLogic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt
@@ -0,0 +1,27 @@
+import com.android.build.api.dsl.ApplicationExtension
+import com.droidconke.doko.configureKotlinAndroid
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.configure
+
+
+class AndroidApplicationConventionPlugin : Plugin<Project> {
+    override fun apply(target: Project) {
+        with(target) {
+            with(pluginManager) {
+                apply("com.android.application")
+                apply("org.jetbrains.kotlin.android")
+                apply("com.dropbox.dependency-guard")
+                apply("doko.android.lint")
+            }
+
+            extensions.configure<ApplicationExtension> {
+                configureKotlinAndroid(this)
+                defaultConfig.targetSdk = 34
+                defaultConfig.minSdk = 28
+                @Suppress("UnstableApiUsage")
+                testOptions.animationsDisabled = true
+            }
+        }
+    }
+}
diff --git a/buildLogic/convention/src/main/kotlin/AndroidApplicationFirebaseConventionPlugin.kt b/buildLogic/convention/src/main/kotlin/AndroidApplicationFirebaseConventionPlugin.kt
new file mode 100644
index 0000000..1dea0c6
--- /dev/null
+++ b/buildLogic/convention/src/main/kotlin/AndroidApplicationFirebaseConventionPlugin.kt
@@ -0,0 +1,38 @@
+import com.android.build.api.dsl.ApplicationExtension
+import com.google.firebase.crashlytics.buildtools.gradle.CrashlyticsExtension
+import com.droidconke.doko.libs
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.configure
+import org.gradle.kotlin.dsl.dependencies
+
+class AndroidApplicationFirebaseConventionPlugin : Plugin<Project> {
+    override fun apply(target: Project) {
+        with(target) {
+            with(pluginManager) {
+                apply("com.google.gms.google-services")
+                apply("com.google.firebase.firebase-perf")
+                apply("com.google.firebase.crashlytics")
+            }
+
+            dependencies {
+                val bom = libs.findLibrary("firebase-bom").get()
+                add("implementation", platform(bom))
+                "implementation"(libs.findLibrary("firebase.analytics").get())
+                "implementation"(libs.findLibrary("firebase.performance").get())
+                "implementation"(libs.findLibrary("firebase.crashlytics").get())
+            }
+
+            extensions.configure<ApplicationExtension> {
+                buildTypes.configureEach {
+                    // Disable the Crashlytics mapping file upload. This feature should only be
+                    // enabled if a Firebase backend is available and configured in
+                    // google-services.json.
+                    configure<CrashlyticsExtension> {
+                        mappingFileUploadEnabled = false
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/buildLogic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt b/buildLogic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt
new file mode 100644
index 0000000..a05e4c7
--- /dev/null
+++ b/buildLogic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt
@@ -0,0 +1,31 @@
+import com.android.build.gradle.LibraryExtension
+import com.droidconke.doko.libs
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.configure
+import org.gradle.kotlin.dsl.dependencies
+
+
+class AndroidFeatureConventionPlugin : Plugin<Project> {
+    override fun apply(target: Project) {
+        with(target) {
+            pluginManager.apply {
+                apply("doko.android.library")
+                apply("doko.hilt")
+            }
+            extensions.configure<LibraryExtension> {
+                testOptions.animationsDisabled = true
+            }
+
+            dependencies {
+
+                add("implementation", libs.findLibrary("androidx.hilt.navigation.compose").get())
+                add("implementation", libs.findLibrary("androidx.lifecycle.runtimeCompose").get())
+                add("implementation", libs.findLibrary("androidx.lifecycle.viewModelCompose").get())
+                add("implementation", libs.findLibrary("androidx.tracing.ktx").get())
+
+                add("androidTestImplementation", libs.findLibrary("androidx.lifecycle.runtimeTesting").get())
+            }
+        }
+    }
+}
diff --git a/buildLogic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt b/buildLogic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt
new file mode 100644
index 0000000..21c0047
--- /dev/null
+++ b/buildLogic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt
@@ -0,0 +1,19 @@
+import com.android.build.gradle.LibraryExtension
+import com.droidconke.doko.configureAndroidCompose
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.apply
+import org.gradle.kotlin.dsl.getByType
+
+
+class AndroidLibraryComposeConventionPlugin : Plugin<Project> {
+    override fun apply(target: Project) {
+        with(target) {
+            apply(plugin = "com.android.library")
+            apply(plugin = "org.jetbrains.kotlin.plugin.compose")
+
+            val extension = extensions.getByType<LibraryExtension>()
+            configureAndroidCompose(extension)
+        }
+    }
+}
diff --git a/buildLogic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt b/buildLogic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt
new file mode 100644
index 0000000..6f3b125
--- /dev/null
+++ b/buildLogic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt
@@ -0,0 +1,44 @@
+import com.android.build.api.variant.LibraryAndroidComponentsExtension
+import com.android.build.gradle.LibraryExtension
+import com.droidconke.doko.configureKotlinAndroid
+import com.droidconke.doko.disableUnnecessaryAndroidTests
+import com.droidconke.doko.libs
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.configure
+import org.gradle.kotlin.dsl.dependencies
+import org.gradle.kotlin.dsl.kotlin
+
+
+
+class AndroidLibraryConventionPlugin : Plugin<Project> {
+    override fun apply(target: Project) {
+        with(target) {
+            with(pluginManager) {
+                apply("com.android.library")
+                apply("org.jetbrains.kotlin.android")
+                apply("doko.android.lint")
+            }
+
+            extensions.configure<LibraryExtension> {
+                configureKotlinAndroid(this)
+                defaultConfig.targetSdk = 34
+                defaultConfig.testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+                testOptions.animationsDisabled = true
+                // The resource prefix is derived from the module name,
+                // so resources inside ":core:module1" must be prefixed with "core_module1_"
+                resourcePrefix = path
+                    .split("""\W""".toRegex()).drop(1).distinct().joinToString(separator = "_").lowercase() + "_"
+            }
+            extensions.configure<LibraryAndroidComponentsExtension> {
+                disableUnnecessaryAndroidTests(target)
+            }
+            dependencies {
+                add("androidTestImplementation", kotlin("test"))
+                add("testImplementation", kotlin("test"))
+
+                add("implementation", libs.findLibrary("androidx.tracing.ktx").get())
+            }
+        }
+    }
+}
diff --git a/buildLogic/convention/src/main/kotlin/AndroidLintConventionPlugin.kt b/buildLogic/convention/src/main/kotlin/AndroidLintConventionPlugin.kt
new file mode 100644
index 0000000..f62b43a
--- /dev/null
+++ b/buildLogic/convention/src/main/kotlin/AndroidLintConventionPlugin.kt
@@ -0,0 +1,32 @@
+import com.android.build.api.dsl.ApplicationExtension
+import com.android.build.api.dsl.LibraryExtension
+import com.android.build.api.dsl.Lint
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.configure
+
+
+class AndroidLintConventionPlugin : Plugin<Project> {
+    override fun apply(target: Project) {
+        with(target) {
+            when {
+                pluginManager.hasPlugin("com.android.application") ->
+                    configure<ApplicationExtension> { lint(Lint::configure) }
+
+                pluginManager.hasPlugin("com.android.library") ->
+                    configure<LibraryExtension> { lint(Lint::configure) }
+
+                else -> {
+                    pluginManager.apply("com.android.lint")
+                    configure<Lint>(Lint::configure)
+                }
+            }
+        }
+    }
+}
+
+private fun Lint.configure() {
+    xmlReport = true
+    checkDependencies = true
+}
+
diff --git a/buildLogic/convention/src/main/kotlin/AndroidRoomConventionPlugin.kt b/buildLogic/convention/src/main/kotlin/AndroidRoomConventionPlugin.kt
new file mode 100644
index 0000000..8a12393
--- /dev/null
+++ b/buildLogic/convention/src/main/kotlin/AndroidRoomConventionPlugin.kt
@@ -0,0 +1,34 @@
+import androidx.room.gradle.RoomExtension
+import com.google.devtools.ksp.gradle.KspExtension
+import com.droidconke.doko.libs
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.configure
+import org.gradle.kotlin.dsl.dependencies
+
+
+class AndroidRoomConventionPlugin : Plugin<Project> {
+    override fun apply(target: Project) {
+        with(target) {
+            pluginManager.apply("androidx.room")
+            pluginManager.apply("com.google.devtools.ksp")
+
+            extensions.configure<KspExtension> {
+                arg("room.generateKotlin", "true")
+            }
+
+            extensions.configure<RoomExtension> {
+                // The schemas directory contains a schema file for each version of the Room database.
+                // This is required to enable Room auto migrations.
+                // See https://developer.android.com/reference/kotlin/androidx/room/AutoMigration.
+                schemaDirectory("$projectDir/schemas")
+            }
+
+            dependencies {
+                add("implementation", libs.findLibrary("room.runtime").get())
+                add("implementation", libs.findLibrary("room.ktx").get())
+                add("ksp", libs.findLibrary("room.compiler").get())
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/buildLogic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt b/buildLogic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt
new file mode 100644
index 0000000..02112cd
--- /dev/null
+++ b/buildLogic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt
@@ -0,0 +1,23 @@
+import com.android.build.gradle.TestExtension
+import com.droidconke.doko.configureKotlinAndroid
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.configure
+
+
+class AndroidTestConventionPlugin : Plugin<Project> {
+    override fun apply(target: Project) {
+        with(target) {
+            with(pluginManager) {
+                apply("com.android.test")
+                apply("org.jetbrains.kotlin.android")
+            }
+
+            extensions.configure<TestExtension> {
+                configureKotlinAndroid(this)
+                defaultConfig.targetSdk = 34
+            }
+        }
+    }
+
+}
diff --git a/buildLogic/convention/src/main/kotlin/HiltConventionPlugin.kt b/buildLogic/convention/src/main/kotlin/HiltConventionPlugin.kt
new file mode 100644
index 0000000..4fe1a9e
--- /dev/null
+++ b/buildLogic/convention/src/main/kotlin/HiltConventionPlugin.kt
@@ -0,0 +1,26 @@
+import com.android.build.gradle.api.AndroidBasePlugin
+import com.droidconke.doko.libs
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.dependencies
+
+
+class HiltConventionPlugin : Plugin<Project> {
+    override fun apply(target: Project) {
+        with(target) {
+            pluginManager.apply("com.google.devtools.ksp")
+            dependencies {
+                add("ksp", libs.findLibrary("hilt.compiler").get())
+                add("implementation", libs.findLibrary("hilt.core").get())
+            }
+
+            /** Add support for Android modules, based on [AndroidBasePlugin] */
+            pluginManager.withPlugin("com.android.base") {
+                pluginManager.apply("dagger.hilt.android.plugin")
+                dependencies {
+                    add("implementation", libs.findLibrary("hilt.android").get())
+                }
+            }
+        }
+    }
+}
diff --git a/buildLogic/convention/src/main/kotlin/JVMLibraryConventionPlugin.kt b/buildLogic/convention/src/main/kotlin/JVMLibraryConventionPlugin.kt
new file mode 100644
index 0000000..5f3c0fe
--- /dev/null
+++ b/buildLogic/convention/src/main/kotlin/JVMLibraryConventionPlugin.kt
@@ -0,0 +1,59 @@
+import com.droidconke.doko.configureKotlinJvm
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+
+/**
+ *
+ * The `JvmLibraryConventionPlugin` class implements the `Plugin<Project>` interface in Gradle,
+ * allowing it to be applied to a Gradle project. This plugin is designed to configure JVM library
+ * projects with specific settings and dependencies.
+ *
+ * The `apply` method is overridden to define the plugin's behavior when it is applied to a project.
+ * Inside this method, the `with(target)` block is used to operate on the `Project` instance passed as the `target` parameter.
+ *
+ * ```
+ * class JvmLibraryConventionPlugin : Plugin<Project> {
+ *     override fun apply(target: Project) {
+ *         with(target) {
+ *             // Configuration code
+ *         }
+ *     }
+ * }
+ * ```
+ *
+ * Within the `with(target)` block, the `pluginManager` is used to apply two plugins:
+ * `org.jetbrains.kotlin.jvm` for Kotlin JVM support and `grapla.android.lint` for linting.
+ *
+ * ```
+ * with(pluginManager) {
+ *     apply("org.jetbrains.kotlin.jvm")
+ *     apply("grapla.android.lint")
+ * }
+ * ```
+ *
+ * Finally, the `configureKotlinJvm` function is called to apply Kotlin-specific configurations to
+ * the JVM project.
+ *
+ * ```
+ * configureKotlinJvm()
+ * ```
+ *
+ * In summary, this plugin sets up a JVM library project with the necessary plugins and configurations,
+ * including Kotlin JVM support and linting.
+ *
+ *
+ * */
+
+
+class JvmLibraryConventionPlugin : Plugin<Project> {
+    override fun apply(target: Project) {
+        with(target) {
+            with(pluginManager) {
+                apply("org.jetbrains.kotlin.jvm")
+                apply("grapla.android.lint")
+            }
+            configureKotlinJvm()
+        }
+    }
+}
+
diff --git a/buildLogic/convention/src/main/kotlin/com/droidconke/doko/AndroidCompose.kt b/buildLogic/convention/src/main/kotlin/com/droidconke/doko/AndroidCompose.kt
new file mode 100644
index 0000000..9ab14ca
--- /dev/null
+++ b/buildLogic/convention/src/main/kotlin/com/droidconke/doko/AndroidCompose.kt
@@ -0,0 +1,54 @@
+package com.droidconke.doko
+
+import com.android.build.api.dsl.CommonExtension
+import org.gradle.api.Project
+import org.gradle.api.provider.Provider
+import org.gradle.kotlin.dsl.configure
+import org.gradle.kotlin.dsl.dependencies
+import org.jetbrains.kotlin.compose.compiler.gradle.ComposeCompilerGradlePluginExtension
+
+
+internal fun Project.configureAndroidCompose(
+    commonExtension: CommonExtension<*, *, *, *, *, *>,
+) {
+    commonExtension.apply {
+        buildFeatures {
+            compose = true
+        }
+
+        dependencies {
+            val bom = libs.findLibrary("androidx-compose-bom").get()
+            add("implementation", platform(bom))
+            add("androidTestImplementation", platform(bom))
+            add("implementation", libs.findLibrary("androidx-compose-ui-tooling-preview").get())
+            add("debugImplementation", libs.findLibrary("androidx-compose-ui-tooling").get())
+        }
+
+        testOptions {
+            unitTests {
+                // For Robolectric
+                isIncludeAndroidResources = true
+            }
+        }
+    }
+
+    extensions.configure<ComposeCompilerGradlePluginExtension> {
+        fun Provider<String>.onlyIfTrue() = flatMap { provider { it.takeIf(String::toBoolean) } }
+
+        fun Provider<*>.relativeToRootProject(dir: String) = flatMap {
+            rootProject.layout.buildDirectory.dir(projectDir.toRelativeString(rootDir))
+        }.map { it.dir(dir) }
+
+        project.providers
+            .gradleProperty("enableComposeCompilerMetrics").onlyIfTrue()
+            .relativeToRootProject("compose-metrics")
+            .let(metricsDestination::set)
+
+        project.providers
+            .gradleProperty("enableComposeCompilerReports").onlyIfTrue()
+            .relativeToRootProject("compose-reports")
+            .let(reportsDestination::set)
+
+        stabilityConfigurationFile = rootProject.layout.projectDirectory.file("compose_compiler_config.conf")
+    }
+}
diff --git a/buildLogic/convention/src/main/kotlin/com/droidconke/doko/AndroidIntsrumentedTests.kt b/buildLogic/convention/src/main/kotlin/com/droidconke/doko/AndroidIntsrumentedTests.kt
new file mode 100644
index 0000000..923f102
--- /dev/null
+++ b/buildLogic/convention/src/main/kotlin/com/droidconke/doko/AndroidIntsrumentedTests.kt
@@ -0,0 +1,11 @@
+package com.droidconke.doko
+
+import com.android.build.api.variant.LibraryAndroidComponentsExtension
+import org.gradle.api.Project
+
+internal fun LibraryAndroidComponentsExtension.disableUnnecessaryAndroidTests(
+    project: Project,
+) = beforeVariants {
+    it.enableAndroidTest = it.enableAndroidTest
+        && project.projectDir.resolve("src/androidTest").exists()
+}
diff --git a/buildLogic/convention/src/main/kotlin/com/droidconke/doko/KotlinAndroid.kt b/buildLogic/convention/src/main/kotlin/com/droidconke/doko/KotlinAndroid.kt
new file mode 100644
index 0000000..eff79fd
--- /dev/null
+++ b/buildLogic/convention/src/main/kotlin/com/droidconke/doko/KotlinAndroid.kt
@@ -0,0 +1,68 @@
+package com.droidconke.doko
+
+import com.android.build.api.dsl.CommonExtension
+import org.gradle.api.JavaVersion
+import org.gradle.api.Project
+import org.gradle.api.plugins.JavaPluginExtension
+import org.gradle.kotlin.dsl.assign
+import org.gradle.kotlin.dsl.configure
+import org.gradle.kotlin.dsl.dependencies
+import org.gradle.kotlin.dsl.provideDelegate
+import org.jetbrains.kotlin.gradle.dsl.JvmTarget
+import org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension
+import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
+import org.jetbrains.kotlin.gradle.dsl.KotlinTopLevelExtension
+
+internal fun Project.configureKotlinAndroid(commonExtension: CommonExtension<*, *, *, *, *, *>) {
+    commonExtension.apply {
+        compileSdk = 34
+
+        defaultConfig {
+            minSdk = 26
+        }
+
+        compileOptions {
+            // Up to Java 11 APIs are available through desugaring
+            // https://developer.android.com/studio/write/java11-minimal-support-table
+            sourceCompatibility = JavaVersion.VERSION_21
+            targetCompatibility = JavaVersion.VERSION_21
+            isCoreLibraryDesugaringEnabled = true
+        }
+    }
+
+    configureKotlin<KotlinAndroidProjectExtension>()
+
+    dependencies {
+        add("coreLibraryDesugaring", libs.findLibrary("android.desugarJdkLibs").get())
+    }
+}
+
+internal fun Project.configureKotlinJvm() {
+    extensions.configure<JavaPluginExtension> {
+        // Up to Java 11 APIs are available through desugaring
+        // https://developer.android.com/studio/write/java11-minimal-support-table
+        sourceCompatibility = JavaVersion.VERSION_21
+        targetCompatibility = JavaVersion.VERSION_21
+    }
+
+    configureKotlin<KotlinJvmProjectExtension>()
+}
+
+private inline fun <reified T : KotlinTopLevelExtension> Project.configureKotlin() =
+    configure<T> {
+        // Treat all Kotlin warnings as errors (disabled by default)
+        // Override by setting warningsAsErrors=true in your ~/.gradle/gradle.properties
+        val warningsAsErrors: String? by project
+        when (this) {
+            is KotlinAndroidProjectExtension -> compilerOptions
+            is KotlinJvmProjectExtension -> compilerOptions
+            else -> TODO("Unsupported project extension $this ${T::class}")
+        }.apply {
+            jvmTarget = JvmTarget.JVM_21
+            allWarningsAsErrors = warningsAsErrors.toBoolean()
+            freeCompilerArgs.add(
+                // Enable experimental coroutines APIs, including Flow
+                "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
+            )
+        }
+    }
diff --git a/buildLogic/convention/src/main/kotlin/com/droidconke/doko/ProjectExtensions.kt b/buildLogic/convention/src/main/kotlin/com/droidconke/doko/ProjectExtensions.kt
new file mode 100644
index 0000000..d70ddb4
--- /dev/null
+++ b/buildLogic/convention/src/main/kotlin/com/droidconke/doko/ProjectExtensions.kt
@@ -0,0 +1,10 @@
+package com.droidconke.doko
+
+import org.gradle.api.Project
+import org.gradle.api.artifacts.VersionCatalog
+import org.gradle.api.artifacts.VersionCatalogsExtension
+import org.gradle.kotlin.dsl.getByType
+
+
+val Project.libs
+    get(): VersionCatalog = extensions.getByType<VersionCatalogsExtension>().named("libs")
diff --git a/compose_compiler_config.conf b/compose_compiler_config.conf
new file mode 100644
index 0000000..40da0eb
--- /dev/null
+++ b/compose_compiler_config.conf
@@ -0,0 +1,11 @@
+// This file contains classes (with possible wildcards) that the Compose Compiler will treat as stable.
+// It allows us to define classes that our not part of our codebase without wrapping them in a stable class.
+// For more information, check https://developer.android.com/jetpack/compose/performance/stability/fix#configuration-file
+
+// We always use immutable classes for our data model, to avoid running the Compose compiler
+// in the module we declare it to be stable here.
+
+
+// Java standard library classes
+java.time.ZoneId
+java.time.ZoneOffset