# Philosophy: CrossFly vs. declarative-reactive

> The mindset shift shared by everyone coming from Flutter, Compose, SwiftUI, or React Native.

Source: https://crossfly.dev/docs/migrate/overview — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# Philosophy: CrossFly vs. declarative-reactive

Before the per-origin translation tables, the **mental contract** that applies to all of them.

## The only change that matters
> **Declarative-reactive frameworks** (Flutter, Compose, SwiftUI, React Native) describe the UI as a
> **function of state** and **rebuild** it when the state changes. **CrossFly is imperative and
> object-oriented:** you create **mutable** `Component` objects **once** (in `onShow()`), **hold
> references**, **change properties**, and call `repaint()`.

There is no re-executed `build()`, no `setState`, no `async/await`. What it has in common with
Flutter/Compose: **everything is rendered via GPU** (OpenGL/WebGL), with no native widgets — the look is
identical across all platforms.

## The mapping of the 4 pillars
| In your framework | In CrossFly |
|---|---|
| re-executed `build()`/`body` | built **once** in `onShow()`; afterwards you mutate objects |
| `setState`/`@State`/`useState` → rebuild | change field + **`repaint()`** (+ `setValidLayout(false)` if the size changed) |
| nested layout widgets | `add(value, comp)` — **`LAY_AUTO`(0f) / `LAY_FILL`(-1f) / fraction** |
| `async`/`await`/`Future` | **`Thread`** + **`Component.onUI(...)`** (explicit threading) |

## The counter, the two models
```java
// Declarative-reactive (pseudo): the state changes → the UI rebuilds itself.
// CrossFly: you keep the reference and update it by hand.
public class Contador extends Window {
   private int n = 0;
   private Label display;
   @Override public void onShow() throws Exception {
      super.onShow();
      setLayout(new VerticalLayout());
      add(LAY_AUTO, display = new Label("0"));
      Button mais = new Button("+");
      mais.onAction(c -> { n++; display.setText(String.valueOf(n)); });  // mutates + repaints
      add(LAY_AUTO, mais);
   }
}
```

## Universal pitfalls (apply to every origin)
- **Hold references** to the components you are going to update (fields of the `Window`) — there is no way
  to "find them again" through rebuilding.
- **Padding/margin** are not widgets: they are `ingap`/`outgap` in the component's **style**.
- **No hot-reload** — it is compiled Java (on the desktop the cycle is fast; see [platforms](/docs/platforms)).
- **Text i18n is manual** — there is no built-in string catalog (see [i18n](/docs/best-practices/internacionalizacao)).
- **Colors are `int` ARGB `0xAARRGGBB`** — there is no `Color` class (use `UIConstants`/`ColorUtils`).

## Choose your origin
[Flutter](/docs/migrate/from-flutter) · [Jetpack Compose](/docs/migrate/from-jetpack-compose) ·
[SwiftUI](/docs/migrate/from-swiftui) · [React Native](/docs/migrate/from-react-native) ·
[TotalCross/SuperWaba](/docs/migrate/from-totalcross)

## See also
- Concept: [State and data flow](/docs/concepts/state-and-data-flow) · [Everything is a Component](/docs/concepts/everything-is-a-component)
