---
title: Computed
description: Derive a read-only value from state with computed(), and read it like a variable.
---

Last page, `count++` changed one piece of text. Now you want text that shows `count` times something else.

You can keep a second `state()` in sync by hand. Don't. Two copies drift apart.

A `computed()` is a value built from other values. You write the recipe once. When an input changes, Markless updates the result and the text that shows it.

Click **Change count**. Then click **Change step**.

<StateComputedFigure />

Notice that either input runs the recipe again. Only the changed input and `total` update on the page.

```tsrx Counter.tsrx
import { computed, state } from '@markless/core';

export default function Counter() @{
	let count = state(1);
	let step = state(2);
	const total = computed(() => count * step);

	<button onClick={() => count++}>{count} × {step} = {total}</button>
}
```

You never list the inputs. The compiler reads the recipe and finds `count` and `step`. You read `total` like a variable, with no call.

Use `computed()` for values. Put side work, like a save or a log line, in the handler that causes it.

:::warning[Why can't I change a computed?]
A computed is read-only. `total = 5` stops the build with `MARKLESS_STATE_READ_ONLY_WRITE`. A change to state inside the recipe gives `MARKLESS_STATE_WRITE_IN_COMPUTED`.
:::

:::danger[Why can't my computed read this variable?]
A recipe can read state, props, imports, and `const` values built from those. Other body variables give `MARKLESS_COMPUTED_READS_RENDER_LOCAL`. Your component runs once. When the recipe runs again later, those variables do not exist.
:::

**Coming from another framework?**

There is no dependency array and no effect hook. The compiler finds each input at build time. Derive values with `computed()`, do side work in event handlers, and do element setup in [`attach`](/state/elements).

**Next:** What if two components need the same `count`? [Shared state →](/state/shared)
