| name | kmp-resources |
| description | Sharing images, strings, fonts, and raw files across Android/iOS/Desktop/Web with the `compose-resources` Gradle plugin. Covers folder layout, qualifier directories, and how platform asset loading still differs. Use when adding shared assets. |
KMP Resources
Instructions
Use the org.jetbrains.compose resources Gradle plugin for all shared assets. It generates a type-safe Res object consumable from commonMain.
1. Setup
plugins {
alias(libs.plugins.composeMultiplatform)
alias(libs.plugins.composeCompiler)
}
compose.resources {
publicResClass = false
packageOfResClass = "com.example.shared.resources"
generateResClass = auto
}
kotlin.sourceSets.commonMain.dependencies {
implementation(compose.components.resources)
}
2. Folder layout
shared/src/commonMain/composeResources/
├── drawable/
│ ├── logo.xml
│ └── hero.png
├── drawable-night/
│ └── logo.xml # dark-mode variant
├── font/
│ └── Inter-Regular.ttf
├── values/
│ └── strings.xml
├── values-es/
│ └── strings.xml # Spanish
├── values-ar/
│ └── strings.xml # Arabic (RTL)
└── files/
└── policy.md # raw resource
Qualifiers follow Android conventions (-night, -es, -w600dp, -ldrtl). The plugin normalizes them across targets.
3. Using resources in Compose
@Composable
fun Header() {
Column {
Image(
painter = painterResource(Res.drawable.logo),
contentDescription = stringResource(Res.string.logo_description),
)
Text(
text = stringResource(Res.string.greeting, "Ada"),
fontFamily = FontFamily(Font(Res.font.Inter_Regular)),
)
}
}
strings.xml:
<resources>
<string name="greeting">Hello, %1$s!</string>
<string name="logo_description">Company logo</string>
<plurals name="item_count">
<item quantity="one">%d item</item>
<item quantity="other">%d items</item>
</plurals>
</resources>
Text(pluralStringResource(Res.plurals.item_count, count, count))
4. Loading raw files
suspend fun loadPolicy(): String =
Res.readBytes("files/policy.md").decodeToString()
On iOS the file is embedded into the framework bundle; on Android into assets; on Desktop into the classpath.
5. Platform-only assets
Some assets must stay platform-native:
- Android:
res/drawable/ic_notification.xml for notification small icons (must be VectorDrawable honoured by the system tray).
- iOS:
Assets.xcassets for launch screens, app icons, and SF Symbols.
Keep shared art in composeResources/ and reference platform assets only from each app module.
6. Images on iOS — performance note
Compose MP on iOS rasterizes PNGs through Skia. For high-res artwork prefer SVG → @Composable ImageVector (converted via svg-to-compose) or multi-density WebP. Avoid giant PNGs; they bloat the framework.
Checklist