Kulid
0.5.0indexedImplements ULIDs with cryptographic security, providing lexicographically sortable, URL-safe, 128-bit compatible identifiers. Supports timestamp-based generation and multiplatform environments with minimal dependencies.
Implements ULIDs with cryptographic security, providing lexicographically sortable, URL-safe, 128-bit compatible identifiers. Supports timestamp-based generation and multiplatform environments with minimal dependencies.
Kulid is a Kotlin Multiplatform implementation of ULIDs (Universally Unique Lexicographically Sortable Identifiers).
ULIDs are identifiers that provide:
This project follows Semantic Versioning with an emphasis on ABI compatibility. Major version numbers will be bumped when changes break ABI compatibility, even if the API remains backward compatible.
For detailed information about changes between versions, please see the CHANGELOG.md file.
This library is still being developed! As a result, there are still features of the ULID spec that are missing, namely:
If you find gaps vs. the spec, please open an issue.
// For Kotlin Multiplatform projects
kotlin {
sourceSets {
commonMain {
dependencies {
implementation("dev.phillipslabs:kulid:1.0") // or whatever the latest version is
}
}
}
}
// For JVM-only projects
dependencies {
implementation("dev.phillipslabs:kulid:1.0") // or whatever the latest version is
}
// For Kotlin Multiplatform projects
kotlin {
sourceSets {
commonMain {
dependencies {
implementation "dev.phillipslabs:kulid:1.0" // or whatever the latest version is
}
}
}
}
// For JVM-only projects
dependencies {
implementation "dev.phillipslabs:kulid:1.0" // or whatever the latest version is
}
// Generate a ULID with the current timestamp
val ulid = ULID.generate()
println(ulid) // Example: 01H1VECZJXS2YFSJVS77XKG8DT
// Generate a ULID with a specific timestamp (in milliseconds)
val timestampInMillis = 1625097600000L // 2021-07-01T00:00:00Z
val ulidWithTimestamp = ULID.generate(timestampInMillis)
println(ulidWithTimestamp)
// Maximum possible ULID value
val maxUlid = ULID.MAX
println(maxUlid) // 7ZZZZZZZZZZZZZZZZZZZZZZZZZ
// Minimum possible ULID value
val minUlid = ULID.MIN
println(minUlid) // 00000000000000000000000000
// Generate strictly increasing ULIDs, even within the same millisecond
val gen = ULID.MonotonicGenerator()
val a = gen.next()
val b = gen.next()
check(a < b) // always true
val parsed = ULID.fromString("01EAWYQD59KTN275S079C9ESX7")
println(parsed) // 01EAWYQD59KTN275S079C9ESX7
// ULID strings are case-insensitive and validated for length/characters
@kotlinx.serialization.Serializable
data class User(val id: ULID)
val json = kotlinx.serialization.json.Json
val u = User(ULID.generate())
val encoded = json.encodeToString(User.serializer(), u)
val decoded = json.decodeFromString(User.serializer(), encoded)
Kulid supports every official Kotlin platform, including all native targets.
ULID.generate() and ULID.MonotonicGenerator() use a cryptographically secure random source. For higher throughput where crypto-strength is not required, pass secureRandom = false.MonotonicGenerator is not thread-safe; share it across threads only with external synchronization, or create one instance per thread/coroutine context.Kulid is organized as a Gradle multi-project build:
:kulid - The main library module containing the ULID implementation:benchmark - A benchmark suite for performance testingKulid has minimal dependencies:
The project includes a benchmark suite built with kotlinx.benchmark to measure the performance of ULID operations.
To run the benchmarks, use the following Gradle command:
./gradlew :benchmark:benchmark
This will execute all benchmarks and generate a report in the benchmark/build/reports/benchmarks directory.
The benchmark suite includes tests for:
If you want to chat more about this library, feel free to talk about it on the Kotlin Slack, or, if you're on matrix, check out #kulid:phillipslabs.dev.
Copyright 2025 David Phillips
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance the License.
You may obtain a copy of the License at
http:
Unless applicable law agreed to writing, software
distributed under the License distributed an BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express implied.
See the License the specific language governing permissions
limitations under the License.
MonotonicGenerator, an IllegalStateException will be thrown due to random component overflow.Surfaced from shared tags and platforms — no rankings paid for.