
Compose-based icon toolkit wrapping Lucide icons: lazy icon registry, configurable icon component, searchable picker with localization, custom icon registration, and build-time generator for bundled icons.
lucide-icon-kmp is a Kotlin Multiplatform wrapper around Lucide Icons for Compose Multiplatform.
It provides a lazy icon registry, configurable LucideIcon, searchable LucideIconPicker, custom
icon registration, and a build-time generator for bundled icons.
This repository is organized as a multi-module Kotlin Multiplatform build:
lucide-core: shared icon models, metadata, lazy registry, search, and bundled icon registration.lucide-compose: Compose Multiplatform UI components such as LucideIcon and LucideIconPicker.lucide-generator: JVM generator that reads vendored Lucide SVG files and emits Kotlin source
files and indexes.sample-compose: sample app targets that demonstrate icon rendering, picker usage, and custom
icon registration.Current publish coordinates are:
group: com.shermant
version: 0.2.0-SNAPSHOT
lucide-core: com.shermant:lucide-icon-kmp:0.2.0-SNAPSHOT
lucide-compose: com.shermant:lucide-icon-kmp-compose:0.2.0-SNAPSHOT
Public Maven coordinates use the published artifact ids above.
The internal Gradle module names :lucide-core and :lucide-compose are not the coordinates you
should declare in a consumer project.
For the current snapshot publish setup, the local publish environment points to:
https://central.sonatype.com/repository/maven-snapshots/
Use that repository only after your snapshot artifacts have been uploaded to Central snapshots. It is a consumer repository URL, not the primary release upload endpoint.
Example dependency setup:
repositories {
maven("https://central.sonatype.com/repository/maven-snapshots/")
google()
mavenCentral()
}
dependencies {
implementation("com.shermant:lucide-icon-kmp:0.2.0-SNAPSHOT")
implementation("com.shermant:lucide-icon-kmp-compose:0.2.0-SNAPSHOT")
}For local integration from another Kotlin Multiplatform project, see LOCAL_USAGE.md.
lucide-core and lucide-compose currently declare these Kotlin Multiplatform targets:
iosX64, iosArm64, iosSimulatorArm64)sample-compose currently includes runnable entry points for:
Current gaps and caveats:
LucideIcon(
name = "activity",
size = 24.dp,
color = Color(0xFF2563EB),
strokeWidth = 2.5f,
)Add the core artifact to the module where you want to use direct icon vectors:
implementation("com.shermant:lucide-icon-kmp:<version>")Generated icons are exposed from com.shermant.lucideiconkmp.core.generated.icons as PascalCase
ImageVector properties that match the file name.
The Maven coordinates remain unchanged; only the source package root changed.
import androidx.compose.material3.Icon
import com.shermant.lucideiconkmp.core.generated.icons.Activity
Icon(
imageVector = Activity,
contentDescription = "Activity",
)For example:
Activity.kt exports Activity
AlignHorizontalJustifyCenter.kt exports AlignHorizontalJustifyCenter
ArrowUpAZ.kt exports ArrowUpAZ
val state = rememberLucideIconPickerState()
val pickerModifiers = LucideIconPickerDefaults.modifiers(
searchBar = Modifier.padding(horizontal = 8.dp),
categories = Modifier.padding(horizontal = 4.dp),
grid = Modifier.padding(horizontal = 4.dp),
pagination = Modifier.padding(top = 8.dp),
)
LucideIconPicker(
state = state,
locale = LucideLocale.Zh,
columns = 4,
pageSize = 24,
searchLimit = 100,
iconSize = 20.dp,
modifiers = pickerModifiers,
onIconSelected = { metadata ->
println(metadata.key.value)
},
)Use style for visual tokens such as colors, spacing, shapes, and labels. Use modifiers when you
need project-specific Compose layout hooks for the picker's main regions: search bar, category tabs,
icon grid, and pagination.
LucideIcons.registry.registerCustomIcon(
name = "brand-logo",
tags = setOf("brand"),
imageVector = customImageVector,
)The repository vendors a pinned Lucide snapshot under
lucide-generator/src/main/resources/lucide-icons and commits the generated Kotlin outputs in
lucide-core.
./gradlew :lucide-generator:generateBundledLucideThis task regenerates the built-in registry, metadata chunks, and icon providers under
lucide-core/src/commonMain/kotlin/com/shermant/core/generated.
Generated icon files are intended to be committed so consumers do not need to regenerate them during normal library usage.
The current pinned Lucide snapshot is 1.16.0; the exact tag, commit, and resource counts are
recorded in lucide-generator/src/main/resources/lucide-icons/VERSION.txt.
This repository now targets Maven Central only.
Use publishCentralSnapshot when VERSION_NAME ends with -SNAPSHOT.
For local publishing in this repository, keep one source of truth per config type:
VERSION_NAME stays in gradle.properties
.secrets file.env is not part of the publish flowscripts/publish-central.ps1, which loads
.secrets into the Gradle properties expected by the publishing pluginBefore running a snapshot publish, set your Central Portal token in .secrets:
MAVEN_CENTRAL_USERNAMEMAVEN_CENTRAL_PASSWORDBecause these publish tasks include Android publications, configure a local Android SDK before running them:
sdk.dir=... to a local root local.properties fileANDROID_HOME / ANDROID_SDK_ROOT in your shell environmentSigning is optional for snapshots.
If you want to sign snapshot artifacts locally, add these to .secrets:
SIGNING_KEY_BASE64 / SIGNING_PASSWORD
Publish a snapshot with:
./gradlew publishCentralSnapshotPublic snapshots that include Apple variants must be published from a macOS host or macOS CI.
Do not publish public snapshots from Windows because they can miss iosArm64 and
iosSimulatorArm64 artifacts.
The repository now includes a macOS GitHub Actions workflow at
.github/workflows/publish-central.yml as the standard public snapshot entry point.
The task fails early if the version is not a snapshot, if the Central token is missing, or if the host is not macOS.
Use publishCentralRelease when VERSION_NAME is a formal release without the -SNAPSHOT suffix.
Formal releases require all of the following:
com.shermant
Recommended credential sources are:
.secrets with MAVEN_CENTRAL_USERNAME, MAVEN_CENTRAL_PASSWORD, SIGNING_KEY_BASE64,
and SIGNING_PASSWORD
Configure a local Android SDK before running the release task because the publication graph also resolves Android artifacts:
sdk.dir=... to a local root local.properties fileANDROID_HOME / ANDROID_SDK_ROOT in your shell environmentPublish and auto-release through Central Portal with:
./gradlew publishCentralReleaseThis build validates the release mode before upload:
VERSION_NAME must not end with -SNAPSHOT
Release publishing that includes Apple variants must also run on macOS. Use the macOS GitHub Actions workflow or a local macOS machine for public release publishing.
scripts/publish-central.ps1 still bridges .secrets into Gradle properties for validation tasks
on Windows, but it intentionally blocks public snapshot and release publishing.
lucide-core-iosarm64 or
lucide-compose-iosarm64, first verify that your dependencies use the public coordinates
lucide-icon-kmp and lucide-icon-kmp-compose.Launch the Wasm browser sample with:
./gradlew :sample-compose:wasmJsBrowserDevelopmentRunBuild the production Wasm distribution with:
./gradlew :sample-compose:wasmJsBrowserDistributionDesktop, Android, and iOS sample entry points also exist in sample-compose, but their execution
depends on the corresponding local toolchains and host environment.
en and zh.locale is set accordingly.pageSize.searchLimit only when the picker query is not blank.lucide-icon-kmp is a Kotlin Multiplatform wrapper around Lucide Icons for Compose Multiplatform.
It provides a lazy icon registry, configurable LucideIcon, searchable LucideIconPicker, custom
icon registration, and a build-time generator for bundled icons.
This repository is organized as a multi-module Kotlin Multiplatform build:
lucide-core: shared icon models, metadata, lazy registry, search, and bundled icon registration.lucide-compose: Compose Multiplatform UI components such as LucideIcon and LucideIconPicker.lucide-generator: JVM generator that reads vendored Lucide SVG files and emits Kotlin source
files and indexes.sample-compose: sample app targets that demonstrate icon rendering, picker usage, and custom
icon registration.Current publish coordinates are:
group: com.shermant
version: 0.2.0-SNAPSHOT
lucide-core: com.shermant:lucide-icon-kmp:0.2.0-SNAPSHOT
lucide-compose: com.shermant:lucide-icon-kmp-compose:0.2.0-SNAPSHOT
Public Maven coordinates use the published artifact ids above.
The internal Gradle module names :lucide-core and :lucide-compose are not the coordinates you
should declare in a consumer project.
For the current snapshot publish setup, the local publish environment points to:
https://central.sonatype.com/repository/maven-snapshots/
Use that repository only after your snapshot artifacts have been uploaded to Central snapshots. It is a consumer repository URL, not the primary release upload endpoint.
Example dependency setup:
repositories {
maven("https://central.sonatype.com/repository/maven-snapshots/")
google()
mavenCentral()
}
dependencies {
implementation("com.shermant:lucide-icon-kmp:0.2.0-SNAPSHOT")
implementation("com.shermant:lucide-icon-kmp-compose:0.2.0-SNAPSHOT")
}For local integration from another Kotlin Multiplatform project, see LOCAL_USAGE.md.
lucide-core and lucide-compose currently declare these Kotlin Multiplatform targets:
iosX64, iosArm64, iosSimulatorArm64)sample-compose currently includes runnable entry points for:
Current gaps and caveats:
LucideIcon(
name = "activity",
size = 24.dp,
color = Color(0xFF2563EB),
strokeWidth = 2.5f,
)Add the core artifact to the module where you want to use direct icon vectors:
implementation("com.shermant:lucide-icon-kmp:<version>")Generated icons are exposed from com.shermant.lucideiconkmp.core.generated.icons as PascalCase
ImageVector properties that match the file name.
The Maven coordinates remain unchanged; only the source package root changed.
import androidx.compose.material3.Icon
import com.shermant.lucideiconkmp.core.generated.icons.Activity
Icon(
imageVector = Activity,
contentDescription = "Activity",
)For example:
Activity.kt exports Activity
AlignHorizontalJustifyCenter.kt exports AlignHorizontalJustifyCenter
ArrowUpAZ.kt exports ArrowUpAZ
val state = rememberLucideIconPickerState()
val pickerModifiers = LucideIconPickerDefaults.modifiers(
searchBar = Modifier.padding(horizontal = 8.dp),
categories = Modifier.padding(horizontal = 4.dp),
grid = Modifier.padding(horizontal = 4.dp),
pagination = Modifier.padding(top = 8.dp),
)
LucideIconPicker(
state = state,
locale = LucideLocale.Zh,
columns = 4,
pageSize = 24,
searchLimit = 100,
iconSize = 20.dp,
modifiers = pickerModifiers,
onIconSelected = { metadata ->
println(metadata.key.value)
},
)Use style for visual tokens such as colors, spacing, shapes, and labels. Use modifiers when you
need project-specific Compose layout hooks for the picker's main regions: search bar, category tabs,
icon grid, and pagination.
LucideIcons.registry.registerCustomIcon(
name = "brand-logo",
tags = setOf("brand"),
imageVector = customImageVector,
)The repository vendors a pinned Lucide snapshot under
lucide-generator/src/main/resources/lucide-icons and commits the generated Kotlin outputs in
lucide-core.
./gradlew :lucide-generator:generateBundledLucideThis task regenerates the built-in registry, metadata chunks, and icon providers under
lucide-core/src/commonMain/kotlin/com/shermant/core/generated.
Generated icon files are intended to be committed so consumers do not need to regenerate them during normal library usage.
The current pinned Lucide snapshot is 1.16.0; the exact tag, commit, and resource counts are
recorded in lucide-generator/src/main/resources/lucide-icons/VERSION.txt.
This repository now targets Maven Central only.
Use publishCentralSnapshot when VERSION_NAME ends with -SNAPSHOT.
For local publishing in this repository, keep one source of truth per config type:
VERSION_NAME stays in gradle.properties
.secrets file.env is not part of the publish flowscripts/publish-central.ps1, which loads
.secrets into the Gradle properties expected by the publishing pluginBefore running a snapshot publish, set your Central Portal token in .secrets:
MAVEN_CENTRAL_USERNAMEMAVEN_CENTRAL_PASSWORDBecause these publish tasks include Android publications, configure a local Android SDK before running them:
sdk.dir=... to a local root local.properties fileANDROID_HOME / ANDROID_SDK_ROOT in your shell environmentSigning is optional for snapshots.
If you want to sign snapshot artifacts locally, add these to .secrets:
SIGNING_KEY_BASE64 / SIGNING_PASSWORD
Publish a snapshot with:
./gradlew publishCentralSnapshotPublic snapshots that include Apple variants must be published from a macOS host or macOS CI.
Do not publish public snapshots from Windows because they can miss iosArm64 and
iosSimulatorArm64 artifacts.
The repository now includes a macOS GitHub Actions workflow at
.github/workflows/publish-central.yml as the standard public snapshot entry point.
The task fails early if the version is not a snapshot, if the Central token is missing, or if the host is not macOS.
Use publishCentralRelease when VERSION_NAME is a formal release without the -SNAPSHOT suffix.
Formal releases require all of the following:
com.shermant
Recommended credential sources are:
.secrets with MAVEN_CENTRAL_USERNAME, MAVEN_CENTRAL_PASSWORD, SIGNING_KEY_BASE64,
and SIGNING_PASSWORD
Configure a local Android SDK before running the release task because the publication graph also resolves Android artifacts:
sdk.dir=... to a local root local.properties fileANDROID_HOME / ANDROID_SDK_ROOT in your shell environmentPublish and auto-release through Central Portal with:
./gradlew publishCentralReleaseThis build validates the release mode before upload:
VERSION_NAME must not end with -SNAPSHOT
Release publishing that includes Apple variants must also run on macOS. Use the macOS GitHub Actions workflow or a local macOS machine for public release publishing.
scripts/publish-central.ps1 still bridges .secrets into Gradle properties for validation tasks
on Windows, but it intentionally blocks public snapshot and release publishing.
lucide-core-iosarm64 or
lucide-compose-iosarm64, first verify that your dependencies use the public coordinates
lucide-icon-kmp and lucide-icon-kmp-compose.Launch the Wasm browser sample with:
./gradlew :sample-compose:wasmJsBrowserDevelopmentRunBuild the production Wasm distribution with:
./gradlew :sample-compose:wasmJsBrowserDistributionDesktop, Android, and iOS sample entry points also exist in sample-compose, but their execution
depends on the corresponding local toolchains and host environment.
en and zh.locale is set accordingly.pageSize.searchLimit only when the picker query is not blank.