Migrating to Android Gradle plugin 9
Short answer: AGP 9 turns on built-in Kotlin and the new DSL by default. To migrate, remove the org.jetbrains.kotlin.android plugin, replace kotlin-kapt with KSP or com.android.legacy-kapt, move android.kotlinOptions to kotlin.compilerOptions, add extra Kotlin sources through android.sourceSets, and replace applicationVariants with the androidComponents API. Start with the AGP Upgrade Assistant in Android Studio. If a plugin blocks you, android.builtInKotlin=false and android.newDsl=false buy time, but Google says that opt-out goes away in AGP 10. The current release is AGP 9.4 (September 2026).
Defaults that changed in AGP 9.0
From Google’s AGP 9.0 release notes. Each can be set back in gradle.properties while you migrate.
| Gradle property | AGP 8.13 → 9.0 | What it means |
|---|---|---|
| android.builtInKotlin | false → true | Kotlin compiles without the kotlin-android plugin |
| android.newDsl | false → true | Only the public DSL interfaces; the legacy variant API is gone |
| android.uniquePackageNames | false → true | Every library needs a distinct package name |
| android.useAndroidx | false → true | AndroidX dependencies by default |
| android.sdk.defaultTargetSdkToCompileSdkIfUnset | false → true | targetSdk defaults to compileSdk, not minSdk |
| android.enableAppCompileTimeRClass | false → true | Apps compile against a non-final R class |
| android.r8.strictFullModeForKeepRules | false → true | -keep class A no longer keeps its default constructor |
| android.proguard.failOnMissingFiles | false → true | A missing keep file fails the build |
| android.defaults.buildfeatures.resvalues | true → false | Turn resValues on only where needed |
Requirements
buildscript classpath. Downgrading KGP is possible only with built-in Kotlin turned off. Android Studio has two agent skills for the upgrade: the AGP 9 upgrade skill for regular apps, bundled in Android Studio, see Android skills in Android Studio, and a JetBrains skill for KMP apps.Built-in Kotlin, step by step
Cannot add extension with name 'kotlin', as there is an extension already registered with that name or The 'org.jetbrains.kotlin.android' plugin is no longer required for Kotlin support since AGP 9.0. Google’s fix has four steps. 1. Remove org.jetbrains.kotlin.android from module and top-level build files and from libs.versions.toml. 2. kapt is incompatible with built-in Kotlin: migrate to KSP, or replace org.jetbrains.kotlin.kapt with com.android.legacy-kapt at your AGP version. 3. Move android { kotlinOptions { } } to kotlin { compilerOptions { } }; jvmTarget now defaults to compileOptions.targetCompatibility. 4. Extra Kotlin source folders go only in android.sourceSets under kotlin.directories; adding them through kotlin.sourceSets or the java set is what triggers «Using kotlin.sourceSets DSL to add Kotlin sources is not allowed with built-in Kotlin». For generated sources, use variant.sources.kotlin with addStaticSourceDirectory or addGeneratedSourceDirectory.The new DSL and variant API
BaseExtension and the old variant API are gone. Replace applicationVariants, libraryVariants and the test variants with androidComponents.onVariants, variantFilter with androidComponents.beforeVariants, and sdkDirectory or adbExecutable with androidComponents.sdkComponents. A ClassCastException saying ApplicationExtensionImpl cannot be cast to BaseExtension means your build logic or a third-party plugin still uses the old types: update the plugin to a version that supports AGP 9. To unblock yourself meanwhile, android.newDsl=false brings the old types back for the whole project, and AGP 9.4 adds android.newDsl.optOut=:module for single modules.Kotlin Multiplatform projects
org.jetbrains.kotlin.multiplatform plugin is no longer compatible with com.android.application or com.android.library in the same module. JetBrains’ migration has two parts: move the Android entry point, such as MainActivity, into a separate androidApp module, then switch the shared module to the Android-KMP library plugin, com.android.kotlin.multiplatform.library. Keep expect and actual declarations in the shared module. As a short-term workaround JetBrains documents android.enableLegacyVariantApi=true. For iOS UI in the same projects, see Compose Multiplatform and Liquid Glass.Flutter projects
android.builtInKotlin=false, and Flutter 3.47 supports android.builtInKotlin=true once an app and all its plugins have migrated. Flutter keeps the AGP DSL compatible with the legacy types for now and plans to remove support for applying KGP later. Projects that don’t apply KGP today shouldn’t migrate to built-in Kotlin. The iOS side of the same release cycle is in the iOS 27 UIScene requirement.Where Censuus fits
Frequently asked questions
Do I still need the kotlin-android plugin with AGP 9?
No. AGP 9 compiles Kotlin with built-in Kotlin, and applying org.jetbrains.kotlin.android causes a build error. Remove it from your build files and version catalog.
Does kapt work with AGP 9?
Not the kotlin-kapt plugin. Google recommends migrating to KSP; if you can’t yet, use com.android.legacy-kapt with the same version as AGP.
How do I fix «kotlin.sourceSets DSL to add Kotlin sources is not allowed with built-in Kotlin»?
Move the folder to android.sourceSets, adding it to kotlin.directories, or register it per variant with variant.sources.kotlin.addStaticSourceDirectory.
How do I opt out of built-in Kotlin?
Set android.builtInKotlin=false and android.newDsl=false in gradle.properties. You can then enable built-in Kotlin module by module with the com.android.built-in-kotlin plugin. Google says the opt-out won’t be possible in AGP 10.
When is AGP 10 released?
Google hasn’t published a date. JetBrains’ KMP guide says it is likely in the second half of 2026; as of 1 October 2026 the latest release is AGP 9.4.
How do I migrate a KMP project to AGP 9?
Move the Android app entry point into its own module and switch the shared module to the com.android.kotlin.multiplatform.library plugin, following JetBrains’ AGP 9 migration guide.
Guides for app developers
- How to market an app: a stage-by-stage plan
- Submit your app for free
- How to get your app to show up in Google search
- How to get your app recommended by AI assistants
- Free app promotion sites, checked for dofollow
- App store optimization checklist: what Apple and Google actually say
- App launch checklist: iOS and Android, step by step
- How to find beta testers for your app
- How to get more app reviews without breaking the store rules
- How to get your app featured on the App Store and Google Play
- App Store and Google Play screenshot sizes: what you must upload
- How to promote an app on Google Play with Play Console’s own tools
- How to promote an iOS app with App Store Connect’s own tools
- App Store keywords: how to fill the 100-character field
- How to market a fitness app: what Apple and Google let you claim
- How to market a kids app: the store rules that shape it
- How to market a finance app: the store rules to know first
- How to market a dating app: the store rules that shape it
- How to market a subscription app: what the stores require of your offer
- How to market a mobile game: the store rules that shape it
- Apple Ads MCP: connect an AI assistant to your campaigns
- How to promote an app on TikTok with creators
- How to promote an app on YouTube with creators
- How to market a VPN app: the store rules to know first
- How to market an AI app: the store rules that shape it
- How to market an education app: schools, parents and learners
- How to localize your App Store and Google Play listing
- Android vitals and Google Play visibility: the thresholds that hide apps
- App Store and Google Play age ratings: what drives them
- App Store privacy labels and Google Play Data safety: what to declare
- Common App Store rejection reasons and how to avoid them
- How to get the first users for your app
- App preview video specs: App Store sizes, length and rules, and the Google Play video
- App Store custom product pages, and the Google Play version
- App icon size for the App Store and Google Play
- App Store phased release and Google Play staged rollouts
- App Store subtitle and promotional text: limits and how to use them
- Google Play feature graphic: size, placement and rules
- TestFlight public link: set it up, limit it, and fix it when it does not work
- App Store promo codes and offer codes: how they work and their limits
- App Store A/B testing: product page optimization and Google Play experiments
- App Store in-app events: limits, badges and media sizes
- App Store Connect analytics: what each metric means
- Google Play store listing reports: clicks, CTR and the 2026 changes
- Google Play target API level requirements for 2026
- Android developer verification: what changed on September 30, 2026
- App Store and Google Play fees in 2026
- Google Play’s 12 testers for 14 days rule, explained
- How to transfer an app to another developer account
- How to remove an app from the App Store and Google Play
- The app account deletion requirement on the App Store and Google Play
- Google Play 16 KB page size requirement: dates, checks and fixes
- Declared Age Range and Play Age Signals: age assurance APIs for app developers
- Xcode 26 and the iOS 26 SDK requirement for App Store Connect
- The iOS privacy manifest: what to declare and how
- Accessibility Nutrition Labels: what to declare on your App Store page
- Google Play’s photo and video permissions policy, explained
- Google Play Billing Library version requirement: what you need to ship now
- App Tracking Transparency: when to ask and how
- App Store Connect API key: create it, store it, use it
- How to submit an In-App Purchase for review
- The Play Integrity API: what it checks and how to use it
- How long app review takes on the App Store and Google Play
- Google Play policy updates in 2026, with the deadlines
- Rosetta 2 end of support: what Mac developers need to do
- Monthly subscriptions with a 12-month commitment on the App Store
- Subscription Bundles, Suites and multiseat purchases on the App Store
- Sign in with Apple private relay email and the new private.icloud.com domain
- App Store Server Notifications V2: switching from V1 and handling every event
- Migrating to StoreKit 2: what is deprecated and what replaces it
- App Store creative assets: headers and search result visuals in iOS 27
- On-Demand Resources is deprecated: moving to Background Assets
- Time Allowances in iOS 27: how your app gets its category
- Android Contact Picker and the new READ_CONTACTS rules
- The Android 17 location button and Google Play’s precise location rules
- Phone verification without READ_CALL_LOG: what replaces call-based checks
- Apple’s EU business terms from October 1, 2026
- Android 17 app memory limits: detect, test and stay under them
- The Android 17 local network permission
- Android 17 background audio hardening
- Cleartext HTTP and certificate transparency on Android 17
- Android 17: lock-free MessageQueue and static final fields
- Android 17 ignores orientation lock and resizability on large screens
- Android 17 behavior changes: a checklist for target SDK 37
- Preparing your app for iPhone Duo
- Google Play subscription grace period and account hold
- Getting your Android app ready for Googlebook
- The Android 17 Handoff API
- ADB Wi-Fi 2.0 wireless debugging
- Android AppFunctions: your app as on-device tools for AI agents
- Android Live Updates: how to qualify for a promoted notification
- App Store Connect webhooks
- Apple Foundation Models: on-device vs Private Cloud Compute
- Using Claude, Codex and other agents in Android Studio
- Gemini Nano for Android developers
- Firebase AI Logic: the App Check deadline and Gemini 2.5 shutdowns
- Swift 6.4: what’s new for app developers
- The Swift SDK for Android
- Publishing your game on Android Auto and Android Automotive OS
- Liquid Glass in a Compose Multiplatform app
- Expo SDK 58: when it ships and what changes
- Device Hub in Xcode 27
- Using the Xcode MCP server with Claude Code, Codex and other agents
- Xcode 27: release, requirements and point releases
- Gemma 4 and Android skills in Android Studio
- The UIScene life cycle is required in iOS 27
- Navigation 3 for Jetpack Compose
- Kotlin 2.4, 2.4.20 and the road to 2.5
- Upgrading your app build to Gradle 9
- The latest Compose BOM and Compose 1.12
- Compose Multiplatform 1.12 and the Hot Reload MCP server
- Opting out of Liquid Glass with UIDesignRequiresCompatibility
- Flutter 3.47 and the latest stable version
- React Native 0.87 and the latest version
- Android Studio Quail 4 and what comes next
- CocoaPods goes read-only: what changes and when
- Fixing YouTube Error 153 in embedded players
- Fixing “APNS token has not been set yet” in Firebase Messaging
- Older iOS Simulator runtimes and Rosetta destinations in Xcode
- Fixing the fmt consteval error in React Native on Xcode 26.4
Put your app in the ranking
Censuus ranks apps by the visits they draw and by sponsorship, no bots. Listing is free; sponsorship raises placement.