This page covers local development tasks for Kalium contributors. The root README stays focused on SDK consumers.
- JDK 21
- Git
- macOS on Apple Silicon for iOS, macOS, and XCFramework builds
- Native libraries under
native/libsfor JVM tests and the CLI
Build native libraries with:
makeAlways pass the native library path when running JVM tests or the CLI:
./gradlew jvmTest -Djava.library.path=./native/libs# Clean build
./gradlew clean build
# JVM tests
./gradlew jvmTest -Djava.library.path=./native/libs
# Android unit tests
./gradlew testDebugUnitTest
./gradlew androidUnitOnlyAffectedTest
./gradlew :logic:testDebugUnitTest
# Single JVM test class
./gradlew :logic:jvmTest --tests "com.wire.kalium.logic.feature.auth.LoginUseCaseTest" -Djava.library.path=./native/libs
# Single JVM test method
./gradlew :logic:jvmTest --tests "com.wire.kalium.logic.feature.auth.LoginUseCaseTest.givenEmailHasLeadingOrTrailingSpaces*" -Djava.library.path=./native/libs
# iOS tests
./gradlew iosSimulatorArm64Test -PUSE_UNIFIED_CORE_CRYPTO=true
./gradlew :core:cryptography:iosSimulatorArm64Test -PUSE_UNIFIED_CORE_CRYPTO=true
./gradlew iOSOnlyAffectedTest -PUSE_UNIFIED_CORE_CRYPTO=true
# JavaScript tests
./gradlew jsTest -PUSE_UNIFIED_CORE_CRYPTO=true
# Lint
./gradlew detekt
# Database migration verification
./gradlew :data:persistence:jvmTest --tests com.wire.kalium.persistence.migrations.VerifyDatabaseMigrationsTest
./gradlew :data:persistence:verifySqlDelightMigration
# Coverage
./gradlew jvmTest koverXmlReport -Djava.library.path=./native/libs
# Aggregate unit-test reports
./gradlew runAllUnitTests
./gradlew aggregateTestResultsControls which CoreCrypto dependency is used:
false: platform-specific crypto artifactstrue: unifiedcore-crypto-kmpartifact
Apple and JavaScript builds require the unified artifact:
./gradlew <task> -PUSE_UNIFIED_CORE_CRYPTO=trueControls provider-level in-memory cache ownership. Consumer builds should set it explicitly; this repository uses LOCAL for standalone builds:
LOCAL: each provider instance owns its cache mapGLOBAL: provider instances share process-global cache maps
Current consumers:
UserStorageProviderUserAuthenticatedNetworkProvider
Use the same flag for any new provider-level cache:
./gradlew <task> -Pkalium.providerCacheScope=LOCAL- Prefer
commonTestfor multiplatform behavior. - Use
jvmTestfor JVM-only behavior. Pass-Djava.library.path=./native/libs. - Use
androidHostTestfor Android unit tests and Robolectric. - Use
androidDeviceTestfor instrumented tests. - Use
appleTestfor iOS/macOS coverage. - Use
jsTestonly for modules with JavaScript support.
Test function names should follow givenX_whenY_thenZ:
fun givenEmailHasLeadingOrTrailingSpaces_whenLoggingIn_thenShouldBeTrimmed()Reusable test infrastructure:
GlobalDBBaseTestandBaseDatabaseTestfrom:data:persistence-test:test:data-mocksfor data-layer fixtures:test:mocksfor network model mocks
Architectural fitness functions live in logic/src/jvmTest/kotlin/com/wire/kalium/logic/architecture:
./gradlew :logic:jvmTest --tests "*architecture*" -Djava.library.path=./native/libsInstall the Detekt plugin and configure:
- Configuration file:
<project-root>/detekt/detekt.yml - Baseline file:
<project-root>/detekt/baseline.yml - Plugin jars:
<project-root>/detekt-rules/build/libs/detekt-rules.jar
Or run Detekt from the terminal:
./gradlew detekt- Keep changes narrow and covered by tests.
- Run tests for every package you modify.
- Add a regression test when fixing a bug.
- Respect the dependency direction:
core -> data -> domain -> logic. - Do not expose
Eithertypes from:logic; wrap them in concrete public result types. - Document architectural changes with an ADR under
docs/adr/.