This content originally appeared on Level Up Coding – Medium and was authored by Richa Sharma
Understanding derivedStateOf in Jetpack Compose : Optimize your recompositions

Introduction
- In Jetpack Compose, recomposition happens automatically and declaratively — which is one of its biggest strengths.
Whenever your UI state changes, Compose intelligently updates only the parts of the UI that need to reflect that change. - However, sometimes you might have a piece of logic — like a complex calculation, heavy validation— that gets re-executed every time your Composable recomposes. If this logic is simple, you may not notice. But if it’s more expensive, it can hurt your app’s performance without you realizing it.
- In this blog, I’ll explain how derivedStateOf helps you optimise these situations. You’ll see how it lets you prevent unnecessary recalculations by automatically caching the result of your derived logic — and only recalculating it when its actual dependencies change.
The Problem
Let’s understand with a sample code problem :
- Let’s say you’re validating an email logic which is getting call in Textfield when we write something in it:

and this gets call in composable function like :

Every time you type:
- richa -> recomposition
- richa.sharma -> recomposition
- richa.sharma@gmail -> recomposition
- The endsWith runs every time. This is small logic, but imagine a complex regex or parsing logic. It runs again because it’s just an expression inside your @Composable function. Compose does not remember the result — it just re-evaluates the whole block.
And the problem is unnecessary repeated work. Not every recomposition changes the input to your calculation. But Compose will still run it, because:
- It re-invokes the @Composable function.
- It re-evaluates all expressions.
Solution : derivedStateOf

- Now Compose tracks email. If email changes, it recalculates isValid.
But if your UI recomposes for any other reason (like theme change, unrelated state), your validation does not recalculate unnecessarily.
Let’s understand how it works internally in Compose
As we know we are calling it inside remember {…} which stores the result of its block across recompositions.

And derivedStateOf creates a special State object (technically DerivedState<T>) that:
- Has a calculation block (email.endsWith(…) here).
- Tracks the inputs.
remember makes sure this same DerivedSnapshotState is reused across future recompositions, so it doesn’t recreate or lose its cached value.
DerivedSnapshotState : It’s a special internal class that:
- Implements State<T> → so it has .value.
- Caches the last computed result.
- Tracks what State objects your lambda reads.
- Knows when to invalidate its cache.

- lets see how this works internally for us

- If the cached value is valid → just return it immediately.
If it’s invalid:
- Run your lambda: email.endsWith("@gmail.com")
- Track that you read email.
- Store the result.
- Return the new result.
email changes → Compose knows you read email inside the lambda → so it marks the derived state as invalid. Next .value read → it re-runs the lambda with the new email.
If email didn’t change → and something else caused recomposition → the cached value is reused → no recalculation → more efficient.

derivedStateOf is Compose’s way to memoize a calculation that depends on State and re-computes only when those specific states change, not every recomposition.
derivedStateOf is your tool for controlling expensive or unnecessary recalculations inside a Composable. It doesn’t stop recompositions — but it makes sure your derived values are recalculated only when their real dependencies change, not on every small UI update.
So the next time you find yourself writing a validation, a filter, a complex regex, or any other derived value inside your UI — pause and ask:
- Does this need to run every time?
- Or can it be wrapped in derivedStateOf for efficiency?
With just a tiny extra line of code, you keep your Compose UI fast, efficient, and predictable — exactly what modern Android apps need.
Reference link
In my next blog, we’ll dive into SideEffect — and see how you can use it to write logs or perform other one-time actions inside a Composable.
Until then, if you learned something new today that helped you understand what’s happening under the hood — please drop a few claps to support my writing!
Take Care 🙂
Understanding derivedStateOf in Jetpack Compose : Optimize your recompositions was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Level Up Coding – Medium and was authored by Richa Sharma