Changelog¶
Unreleased¶
1.6.1¶
2026-10-07
- Enhancement: Extend
ComposeModifierReusedto detect a modifier omitted from a top-leveliforwhenbranch. See #466. - Fix: Make
SlotReusedcheck whether a slot can be used more than once on the same execution path, allowing calls in mutually exclusive branches and respecting early returns. - Fix: Don’t suggest
@NonRestartableComposableon@Preview-annotated composables. - Build against Kotlin
2.4.20. - Build against lint
32.4.1. - Update KSP to
2.3.12.
Special thanks to @dajiaohuang for contributing to this release!
1.6.0¶
2026-08-27
- New: Add
ComposeNonRestartableComposableto suggest@NonRestartableComposablefor composables that only forward to one other composable. - Fix: Exclude extension receivers from
ComposeParameterOrderquick fixes. - Fix: Preserve trailing commas in
ComposeParameterOrderquick fixes. - Fix: Fix
ComposeReadOnlyComposablefalse negatives when read-only composables are used in default argument expressions. - Change: Reclassify
ComposeModifierComposedas aPERFORMANCEissue - Note this requires AGP/lint 9.3+.
Special thanks to @SimonMarquis for contributing to this release!
1.5.5¶
2026-08-25
- Enhancement: Extend
ComposeReadOnlyComposableto suggest@ReadOnlyComposablewhen a composable only calls read-only composables. - Fix: Fix
ComposeRedundantComposablefalse positives relating to composable lambdas. - Build against lint
32.3.2. - Build against AGP lint plugin
9.3.2. - Build against Gradle
9.7.1. - Update KSP to
2.3.11.
Special thanks to @JakeWharton for contributing to this release!
1.5.4¶
2026-08-05
- Enhancement: Add an
ignore-annotatedoption toComposeRedundantComposableas an escape hatch for this check, which can be useful for scenarios where a codebase may generate other contracts based on a composable declaration. - Fix: Fix false positives in
ComposeRedundantComposablefor nullable composable slots and delegated ComposeStatereads. - Fix: Fix false positives in
ComposeRedundantComposablewhen reading composable properties such asCompositionLocal.currentin commonMain code.
1.5.3¶
2026-07-10
- Enhancement: Use Analysis API instead of kotlin-metadata now.
- Enhancement: Suggest just annotating with
@ReadOnlyComposableif a function is only@Composableto access composition locals. - Fix: Fix false positive in
ComposeRedundantComposablewhen invoking composable function parameters in the body. - Fix: Fix IDE false positives in
ComposeRedundantComposablewhen resolving calls to library composables.
Special thanks to @UniqueEVE for contributing to this release!
1.5.2¶
2026-06-03
- Enhancement: See through typealiases when detecting
@Composablefunctions in parameters. - Enhancement: Improve support for context parameters on
ComposeMultipleContentEmitterslint. - Fix: Fix a few false positives with the new
ComposeRedundantComposablecheck. - Fix: Fix Java 17 compatibility.
- Fix: Replace the
stability-checksoption with lint’s standard disabled-by-default issue support forComposeUnstableReceiverandComposeUnstableCollections.
Special thanks to @eboudrant and @kboyarshinov for contributing to this release!
1.5.1¶
2026-05-31
- Enhancement: Add AndroidX mutable scatter collections to known mutable collection types.
- Fix: Keep
ComposeMutableParametersenabled by default for all known mutable parameter types, including a number of mutable collections. - Fix: Fix and clean up some lint explanation text formatting.
Special thanks to @SimonMarquis for contributing to this release!
1.5.0¶
2026-05-26
- Behavior change: The stability checks (
ComposeUnstableReceiver,ComposeMutableParameters,ComposeUnstableCollections) are now disabled by default as they are significantly less important in the era of Compose strong skipping. Re-enable them via the newstability-checksoption inlint.xml. See https://slackhq.github.io/compose-lints/rules/#stability. - New: Add
ComposeItemKeyHashCodeto flaghashCode()used inLazy*/Pageritem keys. Item keys must be unique, but hashCodes are not. See https://slackhq.github.io/compose-lints/rules/#dont-use-hashcode-as-a-key. - New: Add
ComposeRedundantComposableto flag functions/properties annotated@Composablethat don’t use the composition (no@Composablecalls or property reads), so the annotation can be removed. See https://slackhq.github.io/compose-lints/rules/#remove-unnecessary-composable-annotations. - Enhancement: Improve
ModifierReuseddata flow analysis. This addresses several past issues with modifier parameter use in composables. - Enhancement:
ComposeViewModelForwardingis now smarter: it detectsViewModels forwarded inside nested blocks (e.g.Row { Composable(viewModel) }), follows reassignments (e.g.val vm = viewModel; Other(vm)) via data-flow analysis instead of name matching, and no longer flags capitalized non-composable calls (such as event handlers) that happen to take aViewModel. - Fix: Fix
ComposeUnstableReceiverfalse positives on Kotlinvalue classreceivers and on composable members ofvalue classtypes. Value classes are now treated as stable when their underlying property type is stable, including for compiled cross-module classes (via a metadata-aware evaluator). - Fix: Fix the
stability-checksoption being intermittently ignored: each stability check now registers its own option instance, since a single instance shared across issues had its (lint-internal) issue back-reference overwritten depending on class-load order, causing the configured value to resolve against the wrong issue. - Removed: Remove the
ComposeRememberMissingrule in favor of Compose’s ownUnrememberedMutableStatelint, which ships with the Compose runtime, is enabled by default, and covers more state builders without the false positives our rule had. See #490. - Build against lint
32.2.1. - Target Kotlin 2.2 (matches lint 32.*).
Special thanks to @aasitnikov for contributing to this release!
1.4.3¶
2026-05-06
- New: Add slot parameter passing detection to
SlotReusedDetector. - Enhancement:
ComposeUnstableReceiveronly for non-Unit returning functions. - Fix: Fix a false positive for
ModifierReused. - Fix: Fix a false positive when using custom preview annotations.
- Build against Kotlin
2.3.21. - Build against lint
32.2.0. - Build against AGP lint plugin
9.2.0. - Build against Gradle
9.5.0. - Update KSP to
2.3.7. - Update ktfmt to
0.56. - Update detekt to
1.23.8. - Update spotless to
8.4.0. - Update dokka to
2.2.0. - Update mavenPublish to
0.36.0.
1.4.2¶
2024-10-22
- Enhancement: Better handle name shadowing in
SlotReusedlint and reduce false positives. - Test against lint
31.8.0-alpha07. - Various doc fixes.
- Build against lint
31.7.1. - Build against Kotlin
2.0.21. Still targeting Kotlin 1.9 language version (lint 31.7.x’s language version).
Special thanks to @SimonMarquis and @AlexVanyo for contributing to this release!
1.4.1¶
2024-10-02
- Fix: Fix false positives reported by
ComposeContentEmitterReturningValues. - Fix: Fix
content-emittersconfiguration in docs. - Fix: Fix link to multipreview annotations in docs.
Special thanks to @erikghonyan for contributing to this release!
1.4.0¶
2024-10-01
- New: Implement
SlotReusedlint. See https://slackhq.github.io/compose-lints/rules/#do-not-invoke-slots-in-more-than-once-place for more information. - Enhancement: Report the function name for readability in
ComposeContentEmitterReturningValues. - Enhancement: Check for inherited
@Previewannotations up to four levels. - Enhancement: Allow
@VisibleForTesting/@TestOnly-annotated preview composables to be public. - Fix: Don’t report duplicate errors about multiple content emitters.
- Fix: Normalize lint option loading to match with individual issues.
- Fix: Use name of parameter if text is not available.
- Removed: Delete obsolete
ComposeComposableModifierlint check. - Various docs fixes.
- Build against Lint
8.7.0. - Update
apiandminApito16(i.e. lint 8.7.0+). It’s possible this may work with API 15 but we have not tested it. - Test against Lint
8.8.0-alpha04. - Test against K2 UAST.
- Build against Kotlin
2.0.20.
Special thanks to @alexvanyo, @seve-andre, @svenjacobs, @ychescale9, @shahzadansari, and @kozaxinan for contributing to this release!
1.3.1¶
2024-01-25
- Lower the lint API back to
14, not15.
1.3.0¶
2024-01-25
- New: Implement
ModifierComposedcheck to lint against use ofModifier.composed, which is no longer recommended in favor of the newModifier.NodeAPI. - New: Implement
ComposeUnstableReceivercheck to warn when composable extension functions or composables instance functions have unstable receivers/containing classes. - New: Check for property accessors with composition locals.
- Enhancement: The
ComposeComposableModifiermessage now recommends the newModifier.NodeAPI. - Enhancement: Make lints significantly more robust to edge cases like typealiases, import aliases, parentheses, fully-qualified references, and whitespace. Our tests now cover all these cases.
- Enhancement: Update
@Previewdetection to also detect Compose Desktop’s own@Previewannotation. - Enhancement: Improve the
ComposeParameterOrdercheck to only lint the parameter list and add a quickfix. - Enhancement: Add support for checking for loops in multiple content emitters.
- Fix: Fix allowed names config for Unit-returning functions.
- Fix: Ignore context receivers in multiple content emissions lint.
- Fix: Allow nullable types for trailing lambdas in
ComposeParameterOrder. - Fix: Best-effort work around name mangling when comparing name in M2ApiDetector’s allow list.
- Fix: Fix
ComposePreviewPublicto always just require private, remove preview parameter configuration. - Docs: Improve docs for
ComposeContentEmitterReturningValues - Build against lint-api
31.2.2. - Test against lint-api
31.4.0-alpha06. - Raise Kotlin apiVersion/languageVersion to
1.9.0.
Special thanks to @jzbrooks, @joeMalebe, @dellisd for contributing to this release!
1.2.0¶
2023-04-19
- Fix: Only run
ComposeM2Apichecks on Kotlin files. - Update lint current and min API to 14, aka AGP 8.0.0+.
1.1.1¶
2023-03-08
- Fix: Use
setEnabledByDefault(false)instead ofIGNOREinComposeM2Api. This is what we intended before, too, but didn’t realize there was a dedicated API for it. Note that this changes configuration slightly as you must now explicitly enable the rule too and not just the severity. See the docs: https://slackhq.github.io/compose-lints/rules/#use-material-3.
1.1.0¶
2023-03-07
- New: Add
ComposeM2Apirule. This rule can be used to lint against using “Material 2” (androidx.compose.material) APIs in codebases that have migrated to Material 3 (M3). This rule is disabled by default, see the docs for more information: https://slackhq.github.io/compose-lints/rules/#use-material-3. - Enhancement: Add
viewmodel-factorieslint option toComposeViewModelInjection. This allows you to define your own known ViewModel factories. Thanks to @WhosNickDoglio for contributing this! - Build against lint-api to
30.4.2. - Test against lint
31.1.0-alpha08.
1.0.1¶
2023-02-15
Changes¶
- Add installation instructions to index.md by @ZacSweers in https://github.com/slackhq/compose-lints/pull/44
- Fix possible typo in README by @WhosNickDoglio in https://github.com/slackhq/compose-lints/pull/45
- Hopefully fix publish-docs actions by @chrisbanes in https://github.com/slackhq/compose-lints/pull/47
- Update lint-latest to v31.1.0-alpha04 by @slack-oss-bot in https://github.com/slackhq/compose-lints/pull/51
- Update dependency mkdocs-material to v9.0.12 by @slack-oss-bot in https://github.com/slackhq/compose-lints/pull/50
- Downgrade ComposeCompositionLocalUsage to warning by @chrisbanes in https://github.com/slackhq/compose-lints/pull/52
- Misc mutable parameter fixes by @ZacSweers in https://github.com/slackhq/compose-lints/pull/49
- Update plugin spotless to v6.15.0 by @slack-oss-bot in https://github.com/slackhq/compose-lints/pull/54
- Update dependency gradle to v8 by @slack-oss-bot in https://github.com/slackhq/compose-lints/pull/55
- Update Lint baseline by @chrisbanes in https://github.com/slackhq/compose-lints/pull/58
New Contributors¶
- @WhosNickDoglio made their first contribution in https://github.com/slackhq/compose-lints/pull/45
Full Changelog: https://github.com/slackhq/compose-lints/compare/1.0.0...1.0.1
1.0.0¶
2023-02-09
Initial release!
This is a near-full port of the original rule set to lint. It should be mostly at parity with the original rules as well.
The lints target lint-api 30.4.0/lint API 13 and target Java 11.
See the docs for full usage and information: https://slackhq.github.io/compose-lints.
Notes
- ComposeViewModelInjection does not offer a quickfix yet. PRs welcome!
- ComposeUnstableCollections is a warning by default rather than an error.
- CompositionLocalNaming is not ported because this is offered in compose’s bundled lint rules now.