
kexpresso – fluent Kotlin DSL that makes regex readable (KMP, on Maven Central, 0% overhead)
Hi r/Kotlin,
I just shipped kexpresso 0.8.0 to Maven Central. It's a small library I built because I got tired of writing regexes I couldn't read a week later. Sharing it here in case it scratches the same itch for someone — and to get API feedback before I commit to 1.0.
The pitch
Raw regex:
val email = Regex("[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}")
kexpresso:
val email = kexpresso {
startOfText()
email()
endOfText()
}
Same semantics. The DSL compiles to a standard kotlin.text.Regex at construction time — I measured 0% match-time overhead vs raw Regex.
What's interesting
Beyond the builder, four features that came out of dogfooding:
- describe() — walks an internal AST of your pattern and returns a plain-English explanation. Useful when you inherit someone else's regex.
- analyze() — static analysis that flags ReDoS-vulnerable shapes (nested quantifiers, ambiguous alternations). Catches "catastrophic backtracking" before prod.
- examples(count, seed) — generates strings that match the pattern. Deterministic per seed, AST-driven. Great for test data.
- Kexpresso.from(regex) — reverse-engineers a raw regex into the DSL. Round-trippable for the supported subset.
Plus 16 domain helpers (email(), ipv4(), ipv6(), url(), uuid(), base64(), jwt(), macAddress(), etc.) and typed named-captures.
Multiplatform
Full DSL lives in commonMain. Published targets: JVM, JS (IR/Node), wasmJs, linuxX64, mingwX64, macosX64/Arm64, iosArm64/X64/SimulatorArm64. The Wasm/JS Regex engine accepts the full portable test suite identically to JVM; JVM-only constructs (\A, \z, atomic groups, possessive quantifiers) stay JVM-only and remain tested there.
Install
implementation("io.github.elzinko:kexpresso:0.8.0")
No token, no extra repo config — it's on Maven Central. GitHub Packages and JitPack are alternatives.
Honest disclaimers
- Still 0.x. Public API is reasonably stable but I want external feedback before promising SemVer 1.0.
examples(n)is best-effort onRawnodes (domain helpers,Kexpresso.from()), lookarounds, and backreferences — generation never throws but those constructs may not produce a guaranteed match.- Not a regex engine — it's a builder + analyzer on top of
kotlin.text.Regex.
Links
- Repo: https://github.com/elzinko/kexpresso
- Maven Central: https://central.sonatype.com/artifact/io.github.elzinko/kexpresso
- API docs (Dokka): https://elzinko.github.io/kexpresso/
- Runnable guided tour:
./gradlew :samples:runfrom the cloned repo
Specifically looking for feedback on:
- Anything in the public API you'd regret if it were frozen at 1.0?
- Domain helpers I should add (or remove)?
- KMP target coverage gaps you hit?
Roast away — that's what 0.x is for.