KMPify automates the migration of Android Compose projects to align with Compose Multiplatform (KMP) resource conventions.
Each .kt file goes through the following transformation steps:
- Accepts individual
.ktfiles or scans directories recursively for.ktfiles. - Skips non-Kotlin files automatically.
- Extracts the
packagedeclaration at the top of the file to preserve it during reconstruction.
The tool replaces Android-specific imports with their KMP equivalents:
| Android Import | KMP Replacement |
|---|---|
androidx.compose.ui.res.painterResource |
org.jetbrains.compose.resources.painterResource |
androidx.compose.ui.res.stringResource |
org.jetbrains.compose.resources.stringResource |
androidx.compose.ui.text.font.Font |
org.jetbrains.compose.resources.Font |
androidx.annotation.DrawableRes |
org.jetbrains.compose.resources.DrawableResource |
androidx.annotation.StringRes |
org.jetbrains.compose.resources.StringResource |
androidx.compose.ui.tooling.preview.Preview |
org.jetbrains.compose.ui.tooling.preview.Preview |
org.koin.androidx.compose.koinViewModel |
org.koin.compose.viewmodel.koinViewModel |
- Replaces resource references like
R.drawable.iconwithRes.drawable.icon. - Supports
drawable,string, andfonttypes. - Tracks which resources are used to add proper import statements later.
Replaces Android-specific annotations with KMP equivalents.
@DrawableRes icon: Int
@StringRes label: IntBecomes:
icon: DrawableResource
label: StringResourceThe import lines gets replaced as in 3. Import Replacements.
- What: Removes parameters from
@Preview(...)annotations, replacing them with a simple@Preview.- Optionally replaces custom preview class and their imports (e.g.
@MyCustomPrev) with standard@Preview.
- Optionally replaces custom preview class and their imports (e.g.
- Why: KMP’s preview system doesn’t accept Android-specific parameters.
- Example:
// Before @Preview(showBackground = true, name = "Light") // After @Preview
Only inside supported functions like:
painterResource(...)stringResource(...)Font(...)
painterResource(id = R.drawable.logo)Becomes:
painterResource(resource = Res.drawable.logo)- Removes all previous imports.
- Collects:
- Remaining original imports
- New imports for used resources (e.g.
Res.drawable.logo)
- Sorts and rebuilds import block.
- If
dryRun = true: you get aMigrationSummaryand aMigrationReportbut no files gets changed. - Otherwise:
- if no
OutputPathwas specified- Writes to the original file with a new name (
*.kmp.kt)
- Writes to the original file with a new name (
- else writes to the
OutputPath, preserving folder structure.
- if no
For each file, KMPify tracks:
- Whether the file changed
- Number of changes per category:
R Import: whether R class got Replaced or notRes Imports: number of individual resource imports added to the fileDrawable: number ofpainterResourcereplacementsStrings: number ofstringResourcereplacementsImports Added: number of imports replacements as in 3. Import Replacements.- doesn't include the number of individual resource imports.
- click on any row to toggle between number of imports and the actual imports
- You can click on any title to sort the files based on it.