
Compile-time generation of type-safe extension mappers between data classes, with automatic property matching, renaming, nested and collection mapping, enum conversion, custom converters, and reverse mappers.
Every Kotlin codebase has that file. Forty lines of id = id, name = name, email = email that nobody wanted to write and nobody wants to review. Kraft deletes it:
- fun User.toUserDto(): UserDto = UserDto(
- id = id,
- name = name,
- email = email,
- )
+ @MapConfig(source = User::class, target = UserDto::class)
+ object UserMapperval dto = user.toUserDto() // generated at compile timeThat's the whole mapper. Kraft is a KSP processor that generates type-safe extension functions between your data classes — plain, readable Kotlin you can inspect in build/generated. No reflection, no runtime library, nothing to ship.
null around at runtime.commonMain; JVM, Android, iOS, JS, and WasmJs all work.@MapField or @FieldMapping for cross-name mappingList<T> and Set<T> with nested element mapping@MapEnum with auto-matching and custom entry pairs@MapReverse generates the inverse mapper automatically@MapUsing for property-source or whole-source transformations@KraftConverter on a top-level extension is auto-discovered across the module and the classpath, with @OptIn markers propagated onto the generated mapper@MapIgnore and @MapIgnoreField with directional control@MapConfig for mapping without modifying data classesDto / Domain / Entity sides via Gradle to emit short .toDomain() / .toEntity() extensions alongside the verbose mappersMapperGeneratorProvider to plug in your own code generatorKraft runs entirely at build time; the generated mappers are plain Kotlin and the annotations target JVM 1.8, so legacy apps on older runtimes are supported — see Compatibility and legacy projects.
Kraft is published to Maven Central under the com.blu3berry.kraft group (latest version shown in the badge above). Make sure mavenCentral() is in your repositories { } block, then add the dependencies below — replace <version> with the current release.
// build.gradle.kts
plugins {
id("com.google.devtools.ksp") version "<ksp-version>"
}
kotlin {
sourceSets {
commonMain.dependencies {
implementation("com.blu3berry.kraft:kraft-annotations:<version>")
}
}
}
dependencies {
add("kspCommonMainMetadata", "com.blu3berry.kraft:kraft-ksp:<version>")
}// build.gradle.kts
plugins {
id("com.google.devtools.ksp") version "<ksp-version>"
}
dependencies {
implementation("com.blu3berry.kraft:kraft-annotations:<version>")
ksp("com.blu3berry.kraft:kraft-ksp:<version>")
}| Annotation | Purpose | Placement |
|---|---|---|
@MapConfig |
Standalone mapping config | On object |
@MapFrom |
Map from source class | On target data class |
@MapTo |
Map to target class | On source data class |
@MapField |
Rename a property | On property in @MapFrom/@MapTo class |
@MapNested |
|
On property in @MapFrom/@MapTo class |
@MapIgnore |
Skip a property | On property (must have default value) |
@MapUsing |
Custom converter function | On function in @MapConfig object |
@KraftConverter |
Globally discoverable converter | On top-level extension function |
@MapEnum |
Enum-to-enum mapping | On object |
@MapReverse |
Generate inverse mapper | On class or @MapConfig object |
aliasEmitMode |
Per-mapper alias control (AliasEmitMode enum) |
Parameter on @MapConfig and @MapEnum
|
ConverterDirection |
Direction selector for @MapUsing (AUTO / FORWARD / REVERSE) |
Parameter on @MapUsing(direction = …)
|
IgnoreSide |
Direction selector for @MapIgnoreField (TARGET / SOURCE / BOTH) |
Parameter on @MapIgnoreField(direction = …)
|
@FieldMapping |
Config-level rename | In @MapConfig.fieldMappings
|
@NestedMapping |
|
In @MapConfig.nestedMappings
|
@MapIgnoreField |
Config-level ignore | In @MapConfig.ignoredMappings
|
Copyright Kraft Contributors
Licensed under the Apache License, Version 2.0
See LICENSE for the full text.
Every Kotlin codebase has that file. Forty lines of id = id, name = name, email = email that nobody wanted to write and nobody wants to review. Kraft deletes it:
- fun User.toUserDto(): UserDto = UserDto(
- id = id,
- name = name,
- email = email,
- )
+ @MapConfig(source = User::class, target = UserDto::class)
+ object UserMapperval dto = user.toUserDto() // generated at compile timeThat's the whole mapper. Kraft is a KSP processor that generates type-safe extension functions between your data classes — plain, readable Kotlin you can inspect in build/generated. No reflection, no runtime library, nothing to ship.
null around at runtime.commonMain; JVM, Android, iOS, JS, and WasmJs all work.@MapField or @FieldMapping for cross-name mappingList<T> and Set<T> with nested element mapping@MapEnum with auto-matching and custom entry pairs@MapReverse generates the inverse mapper automatically@MapUsing for property-source or whole-source transformations@KraftConverter on a top-level extension is auto-discovered across the module and the classpath, with @OptIn markers propagated onto the generated mapper@MapIgnore and @MapIgnoreField with directional control@MapConfig for mapping without modifying data classesDto / Domain / Entity sides via Gradle to emit short .toDomain() / .toEntity() extensions alongside the verbose mappersMapperGeneratorProvider to plug in your own code generatorKraft runs entirely at build time; the generated mappers are plain Kotlin and the annotations target JVM 1.8, so legacy apps on older runtimes are supported — see Compatibility and legacy projects.
Kraft is published to Maven Central under the com.blu3berry.kraft group (latest version shown in the badge above). Make sure mavenCentral() is in your repositories { } block, then add the dependencies below — replace <version> with the current release.
// build.gradle.kts
plugins {
id("com.google.devtools.ksp") version "<ksp-version>"
}
kotlin {
sourceSets {
commonMain.dependencies {
implementation("com.blu3berry.kraft:kraft-annotations:<version>")
}
}
}
dependencies {
add("kspCommonMainMetadata", "com.blu3berry.kraft:kraft-ksp:<version>")
}// build.gradle.kts
plugins {
id("com.google.devtools.ksp") version "<ksp-version>"
}
dependencies {
implementation("com.blu3berry.kraft:kraft-annotations:<version>")
ksp("com.blu3berry.kraft:kraft-ksp:<version>")
}| Annotation | Purpose | Placement |
|---|---|---|
@MapConfig |
Standalone mapping config | On object |
@MapFrom |
Map from source class | On target data class |
@MapTo |
Map to target class | On source data class |
@MapField |
Rename a property | On property in @MapFrom/@MapTo class |
@MapNested |
|
On property in @MapFrom/@MapTo class |
@MapIgnore |
Skip a property | On property (must have default value) |
@MapUsing |
Custom converter function | On function in @MapConfig object |
@KraftConverter |
Globally discoverable converter | On top-level extension function |
@MapEnum |
Enum-to-enum mapping | On object |
@MapReverse |
Generate inverse mapper | On class or @MapConfig object |
aliasEmitMode |
Per-mapper alias control (AliasEmitMode enum) |
Parameter on @MapConfig and @MapEnum
|
ConverterDirection |
Direction selector for @MapUsing (AUTO / FORWARD / REVERSE) |
Parameter on @MapUsing(direction = …)
|
IgnoreSide |
Direction selector for @MapIgnoreField (TARGET / SOURCE / BOTH) |
Parameter on @MapIgnoreField(direction = …)
|
@FieldMapping |
Config-level rename | In @MapConfig.fieldMappings
|
@NestedMapping |
|
In @MapConfig.nestedMappings
|
@MapIgnoreField |
Config-level ignore | In @MapConfig.ignoredMappings
|
Copyright Kraft Contributors
Licensed under the Apache License, Version 2.0
See LICENSE for the full text.