Compose Multiplatform Desktop JVM support library for building cross-platform desktop applications with declarative UI framework based on Jetpack Compose
—
Resource management in Compose Multiplatform provides tools for bundling, generating, and accessing application resources across different platforms.
abstract class ResourcesExtension {
// Resource configuration API
}The resources extension is available in your build script:
compose {
resources {
// Resource configuration
}
}The plugin provides several tasks for resource processing and code generation.
abstract class GenerateResourceAccessorsTask : DefaultTask() {
@get:InputFiles
abstract val resourcesDirectories: ConfigurableFileCollection
@get:OutputDirectory
abstract val outputDirectory: DirectoryProperty
@TaskAction
fun generate()
}This task generates type-safe accessor code for resources.
abstract class GenerateResClassTask : DefaultTask() {
@get:InputFiles
abstract val resourceFiles: ConfigurableFileCollection
@get:OutputFile
abstract val outputFile: RegularFileProperty
@TaskAction
fun generateResClass()
}Generates resource class definitions.
abstract class PrepareComposeResources : DefaultTask() {
@get:InputFiles
abstract val resourceSources: ConfigurableFileCollection
@get:OutputDirectory
abstract val outputDirectory: DirectoryProperty
@TaskAction
fun prepare()
}Prepares resources for compilation and packaging.
abstract class AssembleTargetResourcesTask : DefaultTask() {
@get:InputFiles
abstract val resourceDirectories: ConfigurableFileCollection
@get:OutputDirectory
abstract val outputDirectory: DirectoryProperty
@TaskAction
fun assembleResources()
}Assembles resources for specific target platforms.
abstract class ResourcesDSL {
// DSL for configuring resource processing
}The resource generation tasks create type-safe accessors:
// Generated by Compose Resources plugin
object Res {
object drawable {
val icon: DrawableResource = DrawableResource("drawable/icon.png")
val logo: DrawableResource = DrawableResource("drawable/logo.svg")
}
object string {
val app_name: StringResource = StringResource("string/app_name")
val welcome_message: StringResource = StringResource("string/welcome_message")
}
object font {
val roboto_regular: FontResource = FontResource("font/roboto_regular.ttf")
}
}sealed class Resource {
abstract val id: String
abstract val items: Set<ResourceItem>
}
data class ResourceItem(
val path: String,
val offset: Long,
val size: Long
)
class DrawableResource(
id: String,
items: Set<ResourceItem>
) : Resource()
class StringResource(
id: String,
items: Set<ResourceItem>
) : Resource()
class FontResource(
id: String,
items: Set<ResourceItem>
) : Resource()
class RawResource(
id: String,
items: Set<ResourceItem>
) : Resource()
enum class ResourceEnvironment {
COMMON,
ANDROID,
IOS,
DESKTOP,
WEB
}import androidx.compose.runtime.*
import org.jetbrains.compose.resources.*
@Composable
fun ResourceExample() {
// Load drawable resource
val icon = painterResource(Res.drawable.icon)
// Load string resource
val appName = stringResource(Res.string.app_name)
// Load font resource
val customFont = fontResource(Res.font.roboto_regular)
Column {
Image(
painter = icon,
contentDescription = appName
)
Text(
text = appName,
fontFamily = FontFamily(customFont)
)
}
}@Composable
fun painterResource(resource: DrawableResource): Painter
@Composable
fun imageResource(resource: DrawableResource): ImageBitmap
@Composable
fun vectorResource(resource: DrawableResource): ImageVector
@Composable
fun stringResource(resource: StringResource): String
@Composable
fun stringResource(resource: StringResource, vararg formatArgs: Any): String
@Composable
fun pluralStringResource(resource: StringResource, quantity: Int): String
@Composable
fun pluralStringResource(resource: StringResource, quantity: Int, vararg formatArgs: Any): String
@Composable
fun fontResource(resource: FontResource): Font
suspend fun readResource(resource: RawResource): ByteArray
suspend fun readResourceText(resource: RawResource): String
suspend fun getDrawableResourceBytes(resource: DrawableResource): ByteArray
suspend fun getStringResourceBytes(resource: StringResource): ByteArray
suspend fun getFontResourceBytes(resource: FontResource): ByteArrayOrganize resources in your project:
src/
├── commonMain/
│ ├── kotlin/
│ └── composeResources/
│ ├── drawable/
│ │ ├── icon.png
│ │ └── logo.svg
│ ├── font/
│ │ └── roboto_regular.ttf
│ ├── string/
│ │ └── strings.xml
│ └── raw/
│ └── data.json
├── desktopMain/
│ └── composeResources/
│ ├── drawable/
│ │ └── desktop_icon.png
│ └── string/
│ └── desktop_strings.xml
└── androidMain/
└── composeResources/
└── drawable/
└── android_icon.pngDefine string resources in XML format:
<!-- src/commonMain/composeResources/string/strings.xml -->
<resources>
<string name="app_name">My Desktop App</string>
<string name="welcome_message">Welcome to %1$s!</string>
<string name="item_count">You have %1$d items</string>
</resources>Use in Compose:
@Composable
fun StringExample() {
val appName = stringResource(Res.string.app_name)
val welcomeMessage = stringResource(Res.string.welcome_message, appName)
val itemCount = stringResource(Res.string.item_count, 42)
Column {
Text(appName)
Text(welcomeMessage)
Text(itemCount)
}
}Resources can be organized by platform:
commonMain/composeResources/ - Shared across all platformsdesktopMain/composeResources/ - Desktop-specific resourcesandroidMain/composeResources/ - Android-specific resourcesiosMain/composeResources/ - iOS-specific resourcesThe resource system automatically selects the appropriate resource based on the target platform, with platform-specific resources taking precedence over common ones.
Resources are automatically processed when you build your project. The generated resource accessors are available in the compose.resources package and can be imported and used directly in your Compose code.
// Build script configuration
compose {
resources {
// Resource processing configuration if needed
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-jetbrains-compose-desktop--desktop-jvm