# How Signy works

Source: https://signy.dev/documentation/1/overview/how-signy-works/

Render once, then let signals update the exact nodes that read them.

## Render once

A component's `render()` runs one time and returns DOM nodes. There is no virtual DOM and no second render. What changes later is wired up during that first render, as small effects bound to the exact text nodes and attributes that need them.

## Automatic tracking

When a function bound in a template reads `signal.value`, the signal remembers it. A write to the signal runs only the functions that read it. You never list dependencies.

```js
html`
  <p>${() => this.count.value}</p>     <!-- live: updates on every write -->
  <p>${this.count.value}</p>           <!-- frozen: the value at render time -->
`;
```

## Updates in a microtask

Signal writes are collected and applied together in a microtask, so five writes in a row cause one DOM update. Use [`batch()`](https://signy.dev/documentation/1/reactivity/batching/index.html.md) to group writes explicitly, and `flushAll()` in tests to apply them at once.

## Ownership

Everything a component creates while rendering belongs to it: bindings, effects created in `setup()`, control flow branches and child components. Unmounting the component disposes all of it.

## Not React

Signy looks familiar, but some React habits do not apply.

- There is no `useState`, `useEffect` or `setState`. State is a signal, side effects are [`effect()`](https://signy.dev/documentation/1/reactivity/effects/index.html.md).
- Do not expect `render()` to run again. Bind a function where a value must update.
- Do not `.map()` a signal array in a template. It renders once. Use [`For`](https://signy.dev/documentation/1/templates/for-and-index/index.html.md).
- Use `class` and `onClick`, not `className` or `onclick`.
