Skip to content

Latest commit

 

History

75 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Valix

Valix Logo

Compile-time generated validation logic for Kotlin. Zero reflection. Generated Kotlin code.

CI Build Status Maven Central Kotlin KMP License

Valix uses Kotlin Symbol Processing (KSP) to generate type-safe validators at compile time—delivering reflection-free validation with zero runtime overhead and zero cold-start delay.

  • Kotlin-Native: Built specifically for Kotlin types, nullability (T?), and data classes.
  • KSP Powered: Generates clean, human-readable procedural Kotlin code at build time.
  • Zero Reflection: Avoids expensive reflection calls and custom Proguard/R8 reflection rules.
  • Multiplatform (KMP): Supports JVM, Android, iOS (iosArm64, iosX64, iosSimulatorArm64), Web (JS), and WebAssembly (Wasm).
  • Framework Ready: First-class integrations for Spring Boot, Ktor, Micronaut, Jetpack Compose, and Coroutines Flow.
  • Schema Generation: Exports OpenAPI 3.1 YAML descriptors and JSON Schema (Draft-07).

30-Second Overview

1. Annotate Data Model

package com.example.user

import io.valix.annotations.*

data class CreateUserRequest(
    @NotBlank
    val username: String,

    @Email
    val email: String,

    @Min(18)
    val age: Int,

    @Sensitive(mask = "[REDACTED]")
    @MinLength(8)
    val password: String
)

2. Execute Validation

val request = CreateUserRequest(username = "john", email = "invalid", age = 15, password = "123")
val result = CreateUserRequestValidator.validate(request)

if (!result.valid) {
    result.errors.forEach { error ->
        println("${error.field}: ${error.message} (Rejected: ${error.rejectedValue})")
    }
}

3. Generated Code Under the Hood

KSP generates standard, human-readable Kotlin procedural code in your build/generated/ksp/ folder:

public object CreateUserRequestValidator : ValixValidator<CreateUserRequest> {
    override fun validate(value: CreateUserRequest, vararg groups: KClass<out Any>, failFast: Boolean): ValidationResult {
        val errors = mutableListOf<ValidationError>()

        val usernameVal = value.username
        if (usernameVal.trim().isEmpty()) {
            errors.add(ValidationError(field = "username", code = "NOT_BLANK", message = "must not be blank", path = "username"))
            if (failFast) return ValidationResult(false, errors)
        }

        val emailVal = value.email
        if (!emailVal.matches(EMAIL_REGEX)) {
            errors.add(ValidationError(field = "email", code = "EMAIL_INVALID", message = "invalid email", path = "email"))
            if (failFast) return ValidationResult(false, errors)
        }

        val ageVal = value.age
        if (ageVal < 18) {
            errors.add(ValidationError(field = "age", code = "MIN_VALUE", message = "must be at least 18", path = "age"))
            if (failFast) return ValidationResult(false, errors)
        }

        val passwordVal = value.password
        if (passwordVal.length < 8) {
            errors.add(ValidationError(field = "password", code = "MIN_LENGTH", message = "minimum length is 8", rejectedValue = "[REDACTED]", path = "password"))
            if (failFast) return ValidationResult(false, errors)
        }

        return ValidationResult(errors.isEmpty(), errors)
    }
}

Comparison Matrix

Feature Valix Bean Validation (JSR 380) Valiktor Konform
Kotlin-First Design Yes No (Java-centric) Yes Yes
Execution Model KSP Codegen Runtime Reflection Runtime Reflection Type-safe DSL
Reflection-Free Yes No No Yes
Kotlin Multiplatform (KMP) Yes (JVM, iOS, JS, Wasm) No No Yes
Spring Boot / Ktor / Micronaut Yes (Dedicated Adapters) Yes (Spring default) Manual Manual
Jetpack Compose Integration Yes No No No
OpenAPI / JSON Schema Export Yes (Built-in Generator) Ecosystem Addons No No
Fail-Fast Execution Mode Yes No No No
Async Validator Codegen Yes No No No

Performance Benchmark (JMH)

Microbenchmarks executed via Java Microbenchmark Harness (JMH) comparing Valix against Hibernate Validator (the reference JSR-380 implementation):

Case Hibernate Validator (JSR-380) Valix Throughput Speedup
Invalid Payload Validation 874,809 ops/sec 7,866,714 ops/sec ~9.0x speedup
Valid Payload Validation 905,822 ops/sec 8,511,063 ops/sec ~9.4x speedup

Bypassing runtime reflection and annotation introspection yields ~9.4x higher operational throughput with zero cold-start latency.


Examples & Benchmarks

For complete integration projects and real-time validation execution benchmarks of Valix across Spring Boot, Micronaut, Ktor, Kotlin Multiplatform (KMP), and Android Jetpack Compose, check out the dedicated examples repository:

👉 DeveloperSyndicate/Valix-Examples


Installation

1. Apply KSP Plugin (build.gradle.kts)

plugins {
    kotlin("jvm") version "2.3.21"
    id("com.google.devtools.ksp") version "2.3.9"
}

2. Add Dependencies

dependencies {
    // Core annotations and runtime
    implementation("com.developersyndicate.valix:valix-core:1.0.5")
    implementation("com.developersyndicate.valix:valix-runtime:1.0.5")

    // KSP annotation processor
    ksp("com.developersyndicate.valix:valix-ksp:1.0.5")
}

Ecosystem & Framework Adapters

  • Spring Boot (valix-spring): Auto-configures SpringMessageResolver to translate message keys using native Spring MessageSource localizations and handles controller parameter validation.
  • Ktor (valix-ktor): Pipeline interceptor validating incoming call request payloads automatically.
  • Micronaut (valix-micronaut): AOP advice (@ValixValidated) and method interceptor for parameter validation.
  • Jetpack Compose (valix-compose): State management via rememberValixForm() and ValidatedTextField.
  • Coroutines Flow (valix-flow): Reactive stream validation operator (validateWith).
  • Architecture Components (valix-viewmodel): ViewModel state binding via ValixFormViewModel.

Key Features

1. Fail-Fast Execution (failFast = true)

Terminate validation execution immediately on the first encountered error to reduce unnecessary processing:

val result = CreateUserRequestValidator.validate(request, failFast = true)

2. Sensitive Data Masking (@Sensitive)

Redact sensitive inputs from error reporting:

data class LoginRequest(
    @NotBlank
    val username: String,

    @Sensitive(mask = "[REDACTED]")
    @MinLength(8)
    val password: String
)

3. Conditional Validation (@ValidateIf)

Evaluate constraints on a property only when sibling properties satisfy condition checks:

data class PaymentRequest(
    val paymentType: String,

    @ValidateIf(field = "paymentType", equals = "CARD")
    @NotBlank(message = "Card number is required for card payments")
    val cardNumber: String?
)

4. Dynamic Parameter Interpolation

Expose constraint parameters (min, max, value) directly inside error message templates:

data class Account(
    @MinLength(value = 8, message = "Minimum length is {min}")
    val username: String
)

5. Programmatic Builder DSL (valixDsl)

Validate third-party or domain models without adding annotations:

val UserValidator = valixDsl<DomainUser> {
    field("email", DomainUser::email) {
        notBlank()
        email()
    }
    field("age", DomainUser::age) {
        min(18)
    }
}

Supported Constraints

String Constraints

@NotNull, @NotBlank, @Email, @MinLength(val), @MaxLength(val), @Pattern(regex), @Url, @PhoneNumber, @Alpha, @AlphaNumeric, @LowerCase, @UpperCase, @Contains(val), @StartsWith(val), @EndsWith(val).

Numeric Constraints

@Min(val), @Max(val), @Range(min, max), @Positive, @PositiveOrZero, @Negative, @NegativeOrZero.

Collection & Enum Constraints

@NotEmpty, @Size(min, max), @AllowedValues(array).


ProGuard & R8 Compatibility

Because Valix generates direct procedural Kotlin code at build time, it performs zero runtime reflection:

  • No Keep Rules Required: You do not need to add -keep rules for your validated data classes or validator classes.
  • Full Code Shrinking & Obfuscation: R8/ProGuard can safely obfuscate, shrink, and optimize both your models and generated validator classes without breaking validation at runtime.
  • Zero Configuration: No consumer-rules.pro file is required.

Documentation & AI Context

Comprehensive documentation is available in the docs/ directory:


License

Valix is open-source software licensed under the Apache 2.0 License.

About

Compile-time generated, zero-reflection validation framework for Kotlin using KSP. Type-safe validation for Android, Ktor, Spring, Micronaut, and Kotlin Multiplatform.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

29 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages