
Modern validation library offers a concise DSL for defining and executing validation rules, supporting type safety, multiple strategies, modular architecture, and built-in localization.
Type-safe, composable validation for Kotlin
KVerify is a validation library that treats validation as first-class code, not configuration. Built for Kotlin developers who want compile-time safety, flexibility, and clean APIs.
Rules are typed values that compose naturally:
// Define rules once
val nicknameRule = RuleList(
StringRules.notBlank(),
StringRules.lengthBetween(3..20),
StringRules.alphanumeric(),
)
// Compose with +
val userRule = nicknameRule + emailRule + ageRule
// Type safety guaranteed at compile time
user.nickname verifyWith nicknameRule // ✅ Works
user.age verifyWith nicknameRule // ❌ Compile errorDifferent use cases need different error handling:
// Collect all errors (for forms, DTOs, APIs)
val result = verifyCollecting {
user.nickname verifyWith nicknameRule
user.email verifyWith emailRule
user.age verifyWith ageRule
}
// Returns: Valid or Invalid(List<Violation>)
// Throw on first error (for business logic, use cases)
verifyThrowing {
order.total verifyWith minimumAmountRule
order.items verifyWith notEmptyRule
}
// Throws: ValidationException on first failureErrors are real objects, not just strings:
data class PasswordTooShortViolation(
val actualLength: Int,
val minimumLength: Int,
) : Violation {
override val reason =
"Password must be at least $minimumLength characters, but is $actualLength"
}
// Handle errors by type
when (val violation = result.violations.first()) {
is PasswordTooShortViolation ->
"Try a longer password (min: ${violation.minimumLength})"
is EmailInvalidViolation ->
"Please check your email format"
else -> violation.reason
}Add dependencies:
dependencies {
implementation("io.github.kverify:kverify-core:2.0.0")
implementation("io.github.kverify:kverify-rule-set:2.0.0")
implementation("io.github.kverify:kverify-named-value:2.0.0")
implementation("io.github.kverify:kverify-named-rule-set:2.0.0")
}Validate anything:
import io.github.kverify.core.context.verifyCollecting
import io.github.kverify.rule.set.provider.*
object StringRules : StringRuleProvider by DefaultStringRuleProvider()
data class SignUpRequest(
val username: String,
val email: String,
val age: Int,
)
fun validateSignUp(request: SignUpRequest): ValidationResult = verifyCollecting {
request.username withName "username" verifyWith RuleList(
NamedStringRules.namedNotBlank(),
NamedStringRules.namedLengthBetween(3..20),
NamedStringRules.namedAlphanumeric(),
)
request.email withName "email" verifyWith emailRule
request.age withName "age" verifyWith ageRule
}
// Use the result
val result = validateSignUp(request)
result.fold(
ifValid = { createUser(request) },
ifInvalid = { violations ->
violations.forEach { println(it.reason) }
// 'username' must be alphanumeric
// 'email' must contain @
// 'age' must be at least 13
}
)| Feature | KVerify | Bean Validation | Konform |
|---|---|---|---|
| Type Safety | ✅ Compile-time | ❌ Runtime annotations | ✅ |
| Composable | ✅ Rules are values | ❌ Annotation-based | |
| Error Strategies | ✅ Multiple strategies | ❌ Always throws | |
| Typed Violations | ✅ Custom error types | ❌ String messages | ❌ String messages |
| Custom Rules | ✅ First-class | ✅ | |
| Multiplatform | ✅ JVM, JS, Native | ✅ |
KVerify is licensed under the Apache 2.0 License.
Built for Kotlin developers who care about type safety and clean code.
Type-safe, composable validation for Kotlin
KVerify is a validation library that treats validation as first-class code, not configuration. Built for Kotlin developers who want compile-time safety, flexibility, and clean APIs.
Rules are typed values that compose naturally:
// Define rules once
val nicknameRule = RuleList(
StringRules.notBlank(),
StringRules.lengthBetween(3..20),
StringRules.alphanumeric(),
)
// Compose with +
val userRule = nicknameRule + emailRule + ageRule
// Type safety guaranteed at compile time
user.nickname verifyWith nicknameRule // ✅ Works
user.age verifyWith nicknameRule // ❌ Compile errorDifferent use cases need different error handling:
// Collect all errors (for forms, DTOs, APIs)
val result = verifyCollecting {
user.nickname verifyWith nicknameRule
user.email verifyWith emailRule
user.age verifyWith ageRule
}
// Returns: Valid or Invalid(List<Violation>)
// Throw on first error (for business logic, use cases)
verifyThrowing {
order.total verifyWith minimumAmountRule
order.items verifyWith notEmptyRule
}
// Throws: ValidationException on first failureErrors are real objects, not just strings:
data class PasswordTooShortViolation(
val actualLength: Int,
val minimumLength: Int,
) : Violation {
override val reason =
"Password must be at least $minimumLength characters, but is $actualLength"
}
// Handle errors by type
when (val violation = result.violations.first()) {
is PasswordTooShortViolation ->
"Try a longer password (min: ${violation.minimumLength})"
is EmailInvalidViolation ->
"Please check your email format"
else -> violation.reason
}Add dependencies:
dependencies {
implementation("io.github.kverify:kverify-core:2.0.0")
implementation("io.github.kverify:kverify-rule-set:2.0.0")
implementation("io.github.kverify:kverify-named-value:2.0.0")
implementation("io.github.kverify:kverify-named-rule-set:2.0.0")
}Validate anything:
import io.github.kverify.core.context.verifyCollecting
import io.github.kverify.rule.set.provider.*
object StringRules : StringRuleProvider by DefaultStringRuleProvider()
data class SignUpRequest(
val username: String,
val email: String,
val age: Int,
)
fun validateSignUp(request: SignUpRequest): ValidationResult = verifyCollecting {
request.username withName "username" verifyWith RuleList(
NamedStringRules.namedNotBlank(),
NamedStringRules.namedLengthBetween(3..20),
NamedStringRules.namedAlphanumeric(),
)
request.email withName "email" verifyWith emailRule
request.age withName "age" verifyWith ageRule
}
// Use the result
val result = validateSignUp(request)
result.fold(
ifValid = { createUser(request) },
ifInvalid = { violations ->
violations.forEach { println(it.reason) }
// 'username' must be alphanumeric
// 'email' must contain @
// 'age' must be at least 13
}
)| Feature | KVerify | Bean Validation | Konform |
|---|---|---|---|
| Type Safety | ✅ Compile-time | ❌ Runtime annotations | ✅ |
| Composable | ✅ Rules are values | ❌ Annotation-based | |
| Error Strategies | ✅ Multiple strategies | ❌ Always throws | |
| Typed Violations | ✅ Custom error types | ❌ String messages | ❌ String messages |
| Custom Rules | ✅ First-class | ✅ | |
| Multiplatform | ✅ JVM, JS, Native | ✅ |
KVerify is licensed under the Apache 2.0 License.
Built for Kotlin developers who care about type safety and clean code.