Ein erster Blick auf Gea, ein Compiler-First-UI-Framework
Gea ist ein compiler-first JavaScript-UI-Framework mit JSX, Klassen-Store und direkten DOM-Patches. Der Artikel prüft Props-Modell, Größe und Reife.
Gea ist ein Compiler-First-JavaScript-UI-Framework: Ein Vite-Plugin liest dein JSX während des Builds, ermittelt, welche DOM-Knoten von welchem State abhängen, und erzeugt direkte DOM-Patches. Es gibt kein Virtual DOM, und zur Laufzeit wird nichts gediffed.
Frameworks, die versprechen, die Runtime wegzukompilieren, tauchen alle paar Monate auf, und der Launch-Beitrag liefert meist den Pitch und die Zahlen, aber kaum etwas zu den Kompromissen. Geas Seiten lesen sich sehr ähnlich, deshalb stellt der folgende Text das Modell so dar, wie das Projekt es beschreibt, benennt die Herkunft jeder Zahl und schaut besonders genau auf den einen Punkt, der sich tatsächlich von React und Vue unterscheidet: bidirektionale Objekt-Props.
Die wichtigsten Erkenntnisse
- Gea verdrahtet Reaktivität zur Compile-Zeit: Ein Vite-Plugin analysiert JSX, ordnet State DOM-Knoten zu und erzeugt gezielte Patches, anstatt ein Virtual DOM auszuliefern.
- Das gesamte Modell besteht aus drei Regeln: Stores sind Klassen, die
Storeerweitern, Komponenten sind Klassen mit einertemplate()-Methode oder einfache Funktionen, und berechnete Werte sind Getter. - Ein Objekt- oder Array-Prop übergibt dem Kind denselben Proxy, den der Parent hält, sodass ein Schreibvorgang im Kind auch den State des Parents verändert. Primitive Werte werden hingegen kopiert.
- Das Projekt gibt 121 B brotli für Hello World an, 4,9 kb für ein interaktives Todo und einen js-framework-benchmark-Score von 1,02 – alles gemessen bei Gea 1.3.0 durch den Maintainer gegen dessen eigene Builds.
- Mit einem einzigen Maintainer, einer frühen Versionsnummer und ohne unabhängige Begutachtung ist Gea eher einen Nachmittags-Spike wert als eine Wette für den Produktivbetrieb.
Was ist Gea?
Gea verlagert Reaktivität von der Laufzeit in den Build. Laut der Projektseite liest das Vite-Plugin dein JSX während der Kompilierung, bestimmt, welche DOM-Knoten von welchen State-Teilen abhängen, und verdrahtet Patches, die nur diese Knoten anfassen. Der Vue-Vergleich formuliert den Gegensatz unmissverständlich: Während Vue eine Render-Funktion erneut ausführt und den resultierenden Baum diffed, führt Gea einfach die Patch-Funktionen aus, die der Compiler bereits generiert hat. Dein State liegt in einfachen Klassen, die Gea in einen tiefen Proxy einwickelt, sodass eine gewöhnliche Zuweisung wie this.count++ genügt, um das DOM zu verändern. Es gibt nichts einzuwickeln und keine Dependency-Liste, die synchron gehalten werden muss. Die README stellt diese Linie als Fortsetzung der früheren Bibliotheken erste.js und regie desselben Maintainers dar, nun mit JSX-Transformationen zur Compile-Zeit.
Wie sieht Geas Modell in drei Zeilen aus?
Geas gesamte Oberfläche passt in drei Regeln: Stores sind Klassen, die Store erweitern, Komponenten sind Klassen mit einer template()-Methode oder einfache Funktionen, und berechnete Werte sind gewöhnliche Getter. Der Counter aus der README zeigt alles davon:
// counter-store.ts
import { Store } from '@geajs/core'
class CounterStore extends Store {
count = 0
increment() { this.count++ }
decrement() { this.count-- }
}
export default new CounterStore()
// app.tsx
import { Component } from '@geajs/core'
import counterStore from './counter-store'
export default class App extends Component {
template() {
return (
<div>
<h1>{counterStore.count}</h1>
<button click={counterStore.increment}>+</button>
<button click={counterStore.decrement}>-</button>
</div>
)
}
}
Die Komponenten-Dokumentation erklärt, dass das Vite-Plugin Funktionskomponenten während des Builds in Klassenkomponenten umschreibt und dass das Template einer Komponente genau einmal ausgeführt wird. Alles danach ist ein Patch statt eines Re-Renders.
Wie unterscheidet sich Geas JSX von dem von React?
Geas JSX sieht wie das von React aus, und eine Konvention muss sich tatsächlich ändern: Schreibe class, wo React className erwartet. Bei Events ist Gea nachsichtiger. Die README schreibt sie als Attribute in Kleinbuchstaben wie click, input und change, aber der Vue-Vergleich in der Dokumentation bestätigt, dass auch onClick, onInput und onChange akzeptiert werden – Handler im React-Stil lassen sich also unverändert übernehmen. Und ref nimmt kein Ref-Objekt: Gea schreibt den DOM-Knoten nach dem Render direkt in die Komponenten-Property.
// React habit // Gea equivalent
<div className="card" <div class="card"
onClick={save} /> click={save} />
Das ref-Muster der Dokumentation besteht aus einem Klassenfeld, das mit null initialisiert wird, ref={this.videoEl} am Element und der anschließenden direkten Verwendung von this.videoEl nach dem Render.
Props: Objekte sind der Proxy des Parents
Die größte Abweichung von React und Vue betrifft das Verhalten nicht-primitiver Props. Geas Komponenten-Dokumentation erklärt, dass das Kind genau denselben Proxy erhält, den der Parent hält, sodass jeder Schreibvorgang des Kindes im State des Parents landet und im DOM des Parents sichtbar wird. Primitive Werte verhalten sich so, wie sich Funktionsargumente in JavaScript verhalten: Das Kind erhält eine Kopie, und eine Neuzuweisung ändert außerhalb des Kindes nichts. Die Dokumentation zeigt ein Kind, das genau dies tut:
export default class Editor extends Component {
rename() {
this.props.user.name = 'Bob' // parent's DOM updates too
}
template({ user }) {
return <button click={this.rename}>{user.name}</button>
}
}
Die Regel gilt unabhängig davon, wie tief der Baum reicht. Übergib dieselbe Referenz an ein Enkelkind, lass es in das Objekt schreiben, und jeder Vorfahre, der diese Daten beobachtet, zeichnet neu. Nichts muss per Callback nach oben gezogen werden, und dazwischen gibt es keinen emit- oder v-model-Schritt.
| Kind aktualisiert Parent | React | Vue | Gea |
|---|---|---|---|
| Objekte/Arrays | Callback-Props | emit / v-model | Direkte Mutation des gemeinsamen Proxys |
| Primitive Werte | Callback-Props | emit / v-model | Nicht möglich (Pass-by-Value) |
Die Dokumentation stellt dies ausschließlich als Vorteil dar, und die offenen Fragen bleiben unbeantwortet. In einem Baum mit 40 Komponenten: Welche Komponente hat dieses Objekt mutiert? Die Einweg-Konvention von React existiert unter anderem deshalb, damit Änderungen einen nachvollziehbaren Ursprung haben; Gea tauscht das gegen Direktheit ein, und niemand hat bislang aufgeschrieben, was dieser Tausch im großen Maßstab kostet. Dasselbe gilt für die Verdrahtung zur Compile-Zeit selbst: Wie der Compiler mit Code umgeht, den er statisch nicht durchschauen kann, thematisiert die Dokumentation nicht.
Größe und Geschwindigkeit, wie das Projekt sie angibt
Jede Performance-Zahl zu Gea ist eine eigene Messung des Projekts gegen die eigenen Builds konkurrierender Frameworks durch den Maintainer. Die Größentabellen der README beziffern eine Hello-World-App auf 121 B brotli-komprimiertes JavaScript, neben den projekteigenen Builds von Solid (3,6 kb), Svelte (8,5 kb), Vue (20,7 kb) und React (50,8 kb), das interaktive Todo bei 4,9 kb. Beide Zahlenreihen wurden bei Gea 1.3.0 aus frischen Vite-8.0.10-Production-Builds erhoben.
Der js-framework-benchmark-Score von 1,02, wobei 1,00 handgeschriebenes Vanilla-JavaScript entspricht, stammt aus dem eigenen Durchlauf der Suite durch das Projekt auf Chrome 147, nicht aus einer offiziell veröffentlichten Runde. Die Aussage „fastest compiled UI framework” auf der Startseite ist eine Behauptung des Projekts, die auf genau diesen selbst erhobenen Zahlen beruht, und kein Befund einer dritten Partei.
Was wird neben Gea ausgeliefert?
Die Paket-Tabelle der README führt @geajs/core, @geajs/vite-plugin, @geajs/ssr für Server-Side Rendering, create-gea für das Scaffolding sowie @geajs/ui (Headless-Komponenten auf Basis von Zag.js) und @geajs/mobile für Mobile-Primitives auf. gea-tools ist eine Erweiterung für VS Code und Cursor, kein npm-Paket.
Der ungewöhnlichere Eintrag ist das AI-Tooling. Der Befehl npx skills add dashersw/gea installiert eine Reihe von Agent Skills, die im Repository unter .cursor/skills/gea-framework liegen und einem KI-Coding-Assistenten die Konventionen an die Hand geben, die er sonst erraten müsste: wie Stores funktionieren, wie Komponenten deklariert werden und wie sich das JSX unterscheidet. Für ein junges Framework, zu dem kein Modell Trainingsdaten hat, ist das Ausliefern der Konventionen als editor-konsumierbare Skills ein pragmatischer Onboarding-Schritt.
Reifegrad: Was die Versionsnummern verraten
Die Vergleichs- und Größentabellen der README sind bei Gea 1.3.0 gemessen, und @geajs/core hat laut den Release Notes des Projekts inzwischen 1.4.0 veröffentlicht. Gea ist MIT-lizenziert und wird von einer einzigen Person gepflegt, Armagan Amcalar. Jede Benchmark- und Größenangabe ist selbst berichtet, und eine unabhängige technische Begutachtung des Frameworks existiert bislang nicht. Für ein Team ist die Schlussfolgerung eindeutig: Das Modell ist in sich konsistent und klein genug, um es an einem Nachmittag zu evaluieren, aber ein einzelner Maintainer, eine frühe Versionsnummer und unverifizierte Zahlen bedeuten, dass es noch keine Evidenzbasis dafür gibt, ein Produkt darauf zu setzen.
Geas wirklich interessante Behauptung ist nicht die Bundle-Größe; es ist die Behauptung, dass einfache Klassen, Funktionen und Getter ein vollständiges Reaktivitätsmodell tragen können, wenn ein Compiler die Verdrahtung übernimmt. Der schnellste Weg, diese Behauptung zu beurteilen, besteht darin, den Counter und das Props-Beispiel von oben aufzusetzen und zu prüfen, ob die bidirektionale Objektsemantik in deiner Art von Codebasis nach Klarheit oder nach Debugging-Risiko fühlt.
FAQs
Wie unterscheidet sich Gea von Solid und Svelte?
Alle drei setzen auf einen Compiler, aber das reaktive Primitiv unterscheidet sich. Solid baut Reaktivität auf Signals auf, die im Browser laufen, und Svelte 5 verwendet seine Runes-Syntax, kompiliert aus seiner eigenen Template-Sprache. Gea hat beides nicht: State liegt in einfachen Klassen, die von einem tiefen Proxy umhüllt werden, und ein Vite-Plugin liest zur Build-Zeit standardkonformes JSX, um direkte DOM-Patches zu verdrahten.
Welche Lifecycle-Hooks haben Gea-Komponenten?
Gea-Klassenkomponenten stellen vier Hooks bereit. created(props) wird zwischen dem Konstruktor und dem ersten Render ausgelöst und ist laut Dokumentation der Ort für Initialisierungslogik. onAfterRender() läuft, sobald das Element der Komponente im Dokument ist und ihre Kinder gemountet sind. onAfterRenderAsync() wartet auf das nächste requestAnimationFrame. dispose() entfernt die Komponente wieder aus dem DOM und baut ihre Observer und Kinder ab. Die Dokumentation verweist auf Klassenkomponenten, sobald du irgendetwas davon benötigst.
Funktioniert Gea mit TypeScript?
Ja. Eine Klassenkomponente deklariert die Form ihrer Props mit 'declare props', einer ambienten Deklaration, die kein JavaScript erzeugt, aber jedem TypeScript-fähigen Editor Autovervollständigung und Prüfung der Attribute ermöglicht – ohne Framework-Plugin. Wenn du den Parameter von template() als this['props'] annotierst, werden diese Typen in die destrukturierten Variablen innerhalb der Methode übernommen; lässt du das weg, fallen sie auf any zurück. Funktionskomponenten erhalten dasselbe Verhalten über eine gewöhnliche Parameter-Annotation.
Wie starte ich ein neues Gea-Projekt?
Erstelle das Scaffolding mit 'npm create gea@latest', dem create-gea-Tool des Projekts. Gea-Builds basieren auf Vite, und @geajs/vite-plugin übernimmt die JSX-Transformation, die Reaktivitäts-Verdrahtung und das Hot Reloading. Die Dokumentation enthält außerdem eine Anleitung zur Browser-Nutzung, um Gea ohne Build-Schritt zu betreiben, neben Anleitungen für den Router, das UI-Kit und die Mobile-Pakete.
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.
Star on GitHub12k