Releases: mttmcknn/dejavu
Release list
DejaVu 0.5.0 — Compose 1.12
DejaVu 0.5.0 targets stable Compose 1.12 and adds regressions for its new runtime and testing behavior. Android Compose 1.11 remains supported, and DejaVu keeps its own version numbers.
Compatibility
- Android: BOM 2026.05.00 through 2026.08.00, with explicit checkpoints at 2026.05.00, 2026.06.01, and 2026.08.00. The release baseline resolves to Compose 1.12.0.
- Multiplatform: built against Compose Multiplatform 1.12.0 and Kotlin 2.4.0. Targets remain Android, JVM desktop, iOS arm64/simulator arm64, and WasmJs.
- Android build requirement: consumers must use compile SDK 37, as declared in the AAR metadata. The release is built with AGP 9.4.0 and Gradle 9.6.0. The intermediate June BOM checkpoint is retired without moving the Compose 1.11 support floor.
- Older projects: DejaVu 0.4.0 is the Compose Multiplatform 1.11 baseline; Compose 1.10 projects should remain on 0.3.1.
What changed
- Added six regressions for keyed
SideEffect, shrinking vararg effect keys, shrinkingrememberkeys, frame assertions without implicit waits, and nested movable content under LinkBuffer. - A deliberately inefficient fixture recomposes four times while its keyed callback stays quiet. Independent unkeyed
SideEffectcounters prove DejaVu records all four recompositions and rejects an incorrect stability budget. - Updated experimental Styles fixtures for the changed
pressedAPI. Version-specific adapters preserve the same stable and intentionally inefficient behaviors on both supported Compose lines. - Configured Wasm executables for Compose 1.12's Skiko bundling requirement. DejaVu continues publishing Wasm KLIB artifacts.
- The Android rule delegates the new
hasPendingWorkandrunWithoutImplicitWaitAPIs. These new methods require Compose 1.12; existing rule methods retain Android 1.11 coverage. - Fixed Android tag mapping when the tracking rule and KMP helper run in the same instrumentation process. Both activity and explicit inspection tables remain visible, and the KMP helper restores previously active tracing on cleanup. A regression verifies the rule → helper → rule sequence with exact independent counts.
- Enabled Android tracking before activity launch, preserving initial inspection-table registration when an earlier test disabled tracking. The setup regression now checks the first real update against an independent counter.
- Added a reproducible standalone consumer build to test packaged Maven artifacts, including a binary built against the release baseline running on older Android Compose versions.
Upgrading
androidTestImplementation("me.mmckenna.dejavu:dejavu:0.5.0")To keep Android Compose 1.11, enforce the selected BOM in both application and instrumentation-test dependencies. A regular platform can allow DejaVu's newer transitive BOM to win. For the Compose Multiplatform 1.11 / compile SDK 36 baseline, use DejaVu 0.4.0.
val composeBom = enforcedPlatform("androidx.compose:compose-bom:2026.06.01")
implementation(composeBom)
androidTestImplementation(composeBom)Keep returning runRecompositionTrackingUiTest directly from KMP tests. Its asynchronous result and suspension behavior are unchanged from 0.4.0. When using runWithoutImplicitWait, perform read-only assertions on the UI thread after settling the frame; mutate state outside that block.
Verification and limits
Fresh local checks passed 229 core and 26 experimental tests on each KMP target. Each Android BOM passed 225 demo and 27 unit tests, plus 20 experimental tests on 1.11 or 26 on 1.12. All packaged consumer checks passed.
The release validation record contains the full local commands, results, and packaged consumer checks. New Compose 1.12 tests run only where those APIs exist; older Android checkpoints retain all core tests and the original 20 experimental regressions, while 1.12 runs 26 experimental tests.
Older Android source checkpoints use API 37; the 1.12 source suite and packaged consumers use API 36; the historical API 26 and 31 device matrix is not claimed as freshly tested. Off-screen lazy items must be brought into view before assertions. Non-Android multi-instance tracking can fall back to a shared function count.
Full change history: CHANGELOG.md.
Documentation
Versioned documentation · Getting started · API reference.
The installation guide includes the required Compose test dependencies, Android runner and manifest setup, compile SDK 37 / min SDK 24 requirements, and KMP test API opt-in. Its examples were verified against 0.5.0 on Android and JVM.
DejaVu 0.4.0 — Compose 1.11
DejaVu 0.4.0 brings Compose 1.11 support and fixes two gaps in multiplatform recomposition testing. It also strengthens the accuracy suite: deliberately inefficient samples still recompose, and DejaVu must report those counts correctly.
Compatibility
- Android: Compose BOM 2026.05.00 through 2026.06.01, with 2026.05.00, 2026.06.00, and 2026.06.01 validated explicitly. The release baseline resolves to Compose 1.11.4.
- Multiplatform: built against Compose Multiplatform 1.11.1 with Kotlin 2.4.0. Targets: Android, JVM desktop, iOS arm64 and simulator arm64, and WasmJs.
- Compose 1.10: stay on DejaVu 0.3.1. Testing v2 requires the newer Compose line. The iosX64 target is removed to match Compose Multiplatform 1.11.
What changed
- Migrated to Compose testing v2 and added
ComposeUiTest.resetRecompositionCounts()for resetting a test budget while preserving composition history. - Fixed asynchronous Wasm tests:
runRecompositionTrackingUiTestnow returns Compose'sTestResult, accepts a suspending body, and keeps tracing active until the body completes. All seven diagnostic-message tests now run on Wasm. Fixes #22. - Fixed lazy-layout inspection on iOS and Wasm by keeping the mutable inspection collection's registration identity stable. All eight previously excluded lazy-row/grid accuracy tests now run on both targets. Fixes #21.
- Corrected Android's recurring tag-mapping fallback and made inspection storage and ground-truth counters safe for concurrent access on JVM/Android.
- Added coverage for Grid, FlexBox, adaptive media queries, Styles, movable content, and the LinkBuffer composer. Exact assertions are checked against independent
SideEffectcounters, including intentional over-recomposition and expected assertion failures. - Added bundled agent skills for onboarding, test writing, diagnosis, and recomposition optimization.
Upgrading
androidTestImplementation("me.mmckenna.dejavu:dejavu:0.4.0")Recompile test modules after upgrading: the KMP helper's function signature changed to support suspension. Return its result directly from each test so the Wasm runner can await it:
@Test
fun titleRemainsStable() = runRecompositionTrackingUiTest {
setTrackedContent { MyScreen() }
waitForIdle()
onNodeWithTag("title").assertStable()
}Verification and limits
Fresh local checks passed 229 core tests and 20 experimental tests on each of JVM, iOS simulator, and Wasm. Each Android BOM passed 224 demo tests, 20 experimental tests, and 27 unit tests. See the validation record for commands, packaging checks, and coverage limits. Local Android instrumentation uses API 37; the historical CI API 26 and 31 matrix is not claimed as freshly tested here.
Android users mixing the tracking rule and KMP helper in one instrumentation process can encounter missing tag mappings or disabled tracing after helper cleanup in 0.4.0; the follow-up 0.5.0 release fixes that integration path.
Off-screen lazy items must be brought into view before assertion. Multi-instance tracking on non-Android targets can fall back to a shared function count; Android provides the most complete per-instance diagnostics.
Full change history: CHANGELOG.md.
Documentation
v0.3.1
Fixed
- Android tag-mapping failure when
Dejavu.enable()is called after the test activity is already resumed (#52)seedActiveActivity()now explicitly seeds the current activity fromDejavuComposeTestRule, soonActivityResumeddoes not need to re-fire- Added
@VolatiletolastResumedReffor safe cross-thread reads onActivityDestroyednow clearslastResumedRefwhen the tracked activity is destroyed
Added
runRecompositionTrackingUiTestandsetTrackedContentpublic APIs for KMP test setup (JVM, iOS, WasmJs)- Dokka API documentation generation
- Regression test for disable/re-enable cycle on a resumed activity
Changed
- Bump Kotlin from 2.2.20 to 2.3.20
- Bump AGP from 8.13.2 to 9.1.0
- Bump Gradle wrapper from 8.13 to 9.4.1
- Bump Compose Multiplatform from 1.10.1 to 1.10.3
- Bump Compose BOM from 2026.01.01 to 2026.03.00
- Bump Activity Compose from 1.7.0 to 1.13.0
- Bump atomicfu from 0.27.0 to 0.32.1
- Bump Robolectric from 4.14.1 to 4.16.1
- Bump core-ktx from 1.17.0 to 1.18.0
- Bump Dokka from 2.1.0 to 2.2.0
- Bump Gradle Actions from 4 to 6
- Bump mkdocs-material from 9.7.4 to 9.7.6
- Bump mike from 2.1.3 to 2.1.4
- Update compatibility tables and CI matrix for 2026.03.01 BOM baseline
Contributors
- Thanks to @LethalMaus for the Android active-activity fix and regression test (#52) — first community contribution to Dejavu!
v0.3.0
Added
- Kotlin Multiplatform support — JVM Desktop, iOS, and WasmJs targets (#13)
- 210 cross-platform tests reaching 98% coverage parity with Android
- Cross-platform tag mapping and per-instance recomposition tracking
- KMP demo targets (Desktop, iOS, Wasm) with shared demo module
Changed
- CI matrix expanded with cross-platform regression tests and hardened verification
- Consolidated fingerprint baseline capture into
resetCounts()for deterministic test setup
Fixed
- Timing-sensitive per-tag counting for multi-instance composables
- Thread safety issues for concurrent access across platforms
- iOS/WasmJs test failures from platform-specific actuals
v0.2.0
[0.2.0] - 2026-03-16
Added
- CompositionObserver integration — automatically tracks per-scope invalidation causes and state dependencies on Compose runtime 1.7+ (#27)
- Enriches
assertStable()/assertRecompositions()error messages with invalidation cause details, value progressions, and state dependency sets - Auto-detected at
Dejavu.enable()— no opt-in required - Backward-compatible: observer classes in separate source set, core compiles against Compose BOMs 2024.06+
- Reentrancy guard in
stateValue()prevents StackOverflowError from DerivedState reads - Uses IdentityHashMap instead of identityHashCode to avoid hash collisions
- Enriches
Fixed
- Per-tag recomposition tracking: false positives from identity-based multi-instance detection, null-fallback to function-level counts, and runtime-internal objects drifting fingerprint hashes (#28)
- Flaky per-tag recomposition detection in CI
Changed
- CI publish workflow auto-updates docs version references at deploy time
dependencies {
debugImplementation("me.mmckenna.dejavu:dejavu:0.2.0")
}