Skip to content

Changelog

Unreleased

1.6.1

2026-10-07

  • Enhancement: Extend ComposeModifierReused to detect a modifier omitted from a top-level if or when branch. See #466.
  • Fix: Make SlotReused check 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 @NonRestartableComposable on @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 ComposeNonRestartableComposable to suggest @NonRestartableComposable for composables that only forward to one other composable.
  • Fix: Exclude extension receivers from ComposeParameterOrder quick fixes.
  • Fix: Preserve trailing commas in ComposeParameterOrder quick fixes.
  • Fix: Fix ComposeReadOnlyComposable false negatives when read-only composables are used in default argument expressions.
  • Change: Reclassify ComposeModifierComposed as a PERFORMANCE issue
  • Note this requires AGP/lint 9.3+.

Special thanks to @SimonMarquis for contributing to this release!

1.5.5

2026-08-25

  • Enhancement: Extend ComposeReadOnlyComposable to suggest @ReadOnlyComposable when a composable only calls read-only composables.
  • Fix: Fix ComposeRedundantComposable false 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-annotated option to ComposeRedundantComposable as 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 ComposeRedundantComposable for nullable composable slots and delegated Compose State reads.
  • Fix: Fix false positives in ComposeRedundantComposable when reading composable properties such as CompositionLocal.current in commonMain code.

1.5.3

2026-07-10

  • Enhancement: Use Analysis API instead of kotlin-metadata now.
  • Enhancement: Suggest just annotating with @ReadOnlyComposable if a function is only @Composable to access composition locals.
  • Fix: Fix false positive in ComposeRedundantComposable when invoking composable function parameters in the body.
  • Fix: Fix IDE false positives in ComposeRedundantComposable when 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 @Composable functions in parameters.
  • Enhancement: Improve support for context parameters on ComposeMultipleContentEmitters lint.
  • Fix: Fix a few false positives with the new ComposeRedundantComposable check.
  • Fix: Fix Java 17 compatibility.
  • Fix: Replace the stability-checks option with lint’s standard disabled-by-default issue support for ComposeUnstableReceiver and ComposeUnstableCollections.

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 ComposeMutableParameters enabled 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 new stability-checks option in lint.xml. See https://slackhq.github.io/compose-lints/rules/#stability.
  • New: Add ComposeItemKeyHashCode to flag hashCode() used in Lazy*/Pager item 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 ComposeRedundantComposable to flag functions/properties annotated @Composable that don’t use the composition (no @Composable calls or property reads), so the annotation can be removed. See https://slackhq.github.io/compose-lints/rules/#remove-unnecessary-composable-annotations.
  • Enhancement: Improve ModifierReused data flow analysis. This addresses several past issues with modifier parameter use in composables.
  • Enhancement: ComposeViewModelForwarding is now smarter: it detects ViewModels 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 a ViewModel.
  • Fix: Fix ComposeUnstableReceiver false positives on Kotlin value class receivers and on composable members of value class types. 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-checks option 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 ComposeRememberMissing rule in favor of Compose’s own UnrememberedMutableState lint, 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: ComposeUnstableReceiver only 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 SlotReused lint 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-emitters configuration 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 SlotReused lint. 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 @Preview annotations 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 ComposeComposableModifier lint check.
  • Various docs fixes.
  • Build against Lint 8.7.0.
  • Update api and minApi to 16 (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, not 15.

1.3.0

2024-01-25

  • New: Implement ModifierComposed check to lint against use of Modifier.composed, which is no longer recommended in favor of the new Modifier.Node API.
  • New: Implement ComposeUnstableReceiver check 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 ComposeComposableModifier message now recommends the new Modifier.Node API.
  • 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 @Preview detection to also detect Compose Desktop’s own @Preview annotation.
  • Enhancement: Improve the ComposeParameterOrder check 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 ComposePreviewPublic to 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 ComposeM2Api checks 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 of IGNORE in ComposeM2Api. 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 ComposeM2Api rule. 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-factories lint option to ComposeViewModelInjection. 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

New Contributors

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.