
Declare singleton schemas offering typed compile-time field access and serializable wire definitions; consumers decode, diff, compose, namespaced-merge, and walk entries without shared code.
A Kotlin Multiplatform library for declaring typed schemas and sharing them as serializable data.
Add to your JVM dependencies or Multiplatform commonMain dependencies:
implementation("com.eignex:skema:0.3.0")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.12.0")skema uses compile-only serialization dependencies, so your application supplies the runtime. Apply the Kotlin serialization plugin at the same version as your Kotlin plugin.
Define the configuration types your schema accepts, then register entries with helpers that return typed keys:
import com.eignex.skema.*
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable sealed interface FormField
@Serializable @SerialName("Bool") data object BoolField : FormField
@Serializable @SerialName("Int") data class IntField(val min: Int, val max: Int) : FormField
data class BoolKey(val name: String)
data class IntKey(val name: String, val min: Int, val max: Int)
abstract class FormSchema : Schema<FormField>() {
protected fun bool(name: String): BoolKey {
add(name, BoolField)
return BoolKey(name)
}
protected fun int(min: Int, max: Int) =
register(IntField(min, max)) { IntKey(it, min, max) }
}
object SignupFormSchema : FormSchema() {
val acceptsTos = bool("acceptsTos")
val age by int(13, 120)
}Use add for an explicit name or register to take the property name. Duplicate names throw. Calling definition() validates the entries and takes a snapshot for serialization:
val serializer = SchemaDef.serializer(FormField.serializer())
val wire = SchemaJson.encodeToString(serializer, SignupFormSchema.definition())
val definition = SchemaJson.decodeFromString(serializer, wire)The JSON contains the entry names and configuration:
{"entries":{"acceptsTos":{"$type":"Bool"},"age":{"$type":"Int","min":13,"max":120}}}Consumers share the configuration types and read definition.entries without needing the original schema object. Applications handle field values and input validation.
Compact JSON
encodes nodes as operator objects, names, or numeric literals.
Node bodies decode with your Json settings.
Serializer-derived JSON Schema
uses a JsonNodeCatalog to find nested compact vocabularies. Compact JSON requires the default
polymorphic discriminator mode and no JSON naming strategy.
A Kotlin Multiplatform library for declaring typed schemas and sharing them as serializable data.
Add to your JVM dependencies or Multiplatform commonMain dependencies:
implementation("com.eignex:skema:0.3.0")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.12.0")skema uses compile-only serialization dependencies, so your application supplies the runtime. Apply the Kotlin serialization plugin at the same version as your Kotlin plugin.
Define the configuration types your schema accepts, then register entries with helpers that return typed keys:
import com.eignex.skema.*
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable sealed interface FormField
@Serializable @SerialName("Bool") data object BoolField : FormField
@Serializable @SerialName("Int") data class IntField(val min: Int, val max: Int) : FormField
data class BoolKey(val name: String)
data class IntKey(val name: String, val min: Int, val max: Int)
abstract class FormSchema : Schema<FormField>() {
protected fun bool(name: String): BoolKey {
add(name, BoolField)
return BoolKey(name)
}
protected fun int(min: Int, max: Int) =
register(IntField(min, max)) { IntKey(it, min, max) }
}
object SignupFormSchema : FormSchema() {
val acceptsTos = bool("acceptsTos")
val age by int(13, 120)
}Use add for an explicit name or register to take the property name. Duplicate names throw. Calling definition() validates the entries and takes a snapshot for serialization:
val serializer = SchemaDef.serializer(FormField.serializer())
val wire = SchemaJson.encodeToString(serializer, SignupFormSchema.definition())
val definition = SchemaJson.decodeFromString(serializer, wire)The JSON contains the entry names and configuration:
{"entries":{"acceptsTos":{"$type":"Bool"},"age":{"$type":"Int","min":13,"max":120}}}Consumers share the configuration types and read definition.entries without needing the original schema object. Applications handle field values and input validation.
Compact JSON
encodes nodes as operator objects, names, or numeric literals.
Node bodies decode with your Json settings.
Serializer-derived JSON Schema
uses a JsonNodeCatalog to find nested compact vocabularies. Compact JSON requires the default
polymorphic discriminator mode and no JSON naming strategy.