That's how Emacs works, although it uses (your choice of a set of) GUI toolkits. Not sure if you mean one single toolkit that covers both and looks identical. I guess Emacs would still mostly qualify.
No you are right, but that’s irrelevant to my point. The point being that Flutter is an example of a “react-like” framework to write UI that renders to multiple backends.
not really, it's important to me that we don't flatten things into a canvas rendering system, the idea is to remap abstract UI structures onto various projections (terminal, html, else)
I see. We’re talking about different levels of abstraction.
There are two approaches there. One is to project abstract UI onto platform controls (React Native), the other is to use “drawing” (Flutter). Both have their pros and cons.
The main drawback of abstracting over controls is that each platform works very differently and the abstraction quickly starts leaking. Also some of the targets don’t have any controls like the terminal. All you can do in a terminal is draw text in rows and columns.
That is why most (not all) cross platform frameworks abstract on the drawing level. Gtk, Qt, Flutter, Druid, Dear ImGui and many more.
I agree that it's not well defined, but I'd guess that a good rule of thumb is "fd 0 isn't isatty, and the process has the info (from env vars or arguments) necessary to open graphically" with an additional switch for overriding in either direction.