Kotlin & Java quickstart
By the end of this page you will have a Kotlin program that creates an end-to-end encrypted document store, writes a todo, and reads it back. The same client works from Java, Spring, Ktor, or any other JVM backend.
How it works
The JVM client drives the real MindooDB engine, which runs in a small Node.js sidecar on the same machine. They talk over an authenticated loopback WebSocket, and each user session gets its own process, so decrypted keys never mix. Encryption, signatures, sync, and access control are the same code that runs in Node.js, browsers, and React Native.
1) Get the client and the sidecar
You need JDK 21+ and Node.js 22.13+. Clone both projects next to each other and build the sidecar:
git clone https://github.com/klehmann/mindoodb-jvm-bridge.git
git clone https://github.com/klehmann/mindoodb-kmp-client.git
cd mindoodb-jvm-bridge && npm install && npm run build && cd .. Then add the client to your Gradle build, for example as an included build in settings.gradle.kts:
// settings.gradle.kts
includeBuild("../mindoodb-kmp-client")
// build.gradle.kts
dependencies {
implementation("com.mindoo.db:mindoodb-kmp-client:0.0.1")
} 2) Create Main.kt
Sidecar.start launches the engine. createTenant generates all cryptographic keys and registers the first user in one step. After that, we open a session, create a document, and read it back — every change is signed and encrypted before it is stored.
import com.mindoo.db.bridge.*
import java.nio.file.Paths
import kotlinx.coroutines.runBlocking
fun main() = runBlocking {
// Starts the Node.js sidecar that runs the MindooDB engine
val sidecar = Sidecar.start(
Paths.get("../mindoodb-jvm-bridge/dist/index.js"),
Paths.get("./mindoodb-data"),
)
// One call creates admin + user keys, KeyBag, and directory
MindooDBBridge.createTenant(
sidecar.endpoint,
tenantId = "my-first-tenant",
adminName = "cn=admin/o=demo", adminPassword = "admin-password",
userId = "cn=alice/o=demo", password = "user-password",
databases = listOf("todos"),
)
val session = MindooDBBridge.openSession(
sidecar.endpoint, "my-first-tenant", "cn=alice/o=demo",
"user-password", listOf("todos"),
)
// Create a todo document and read it back
val todos = session.database("todos")
val todo = todos.documents.create(mapOf("title" to "Buy milk", "done" to false))
println("Loaded todo: " + todos.documents.get(todo.id).data)
session.close()
sidecar.stop()
} 3) Run
./gradlew run Expected output:
Loaded todo: {"_attachments":[],"done":false,"title":"Buy milk"} What's next?
The full guide covers field types, rich text, attachments, queries, virtual views, the changefeed, publishing to a server, sync, adding users, and calling the client from Java.