12k
All articles

Premier aperçu de Gea, un framework UI orienté compilation

Gea est un framework UI JavaScript compiler-first qui utilise JSX, des stores en classes et des patchs DOM directs. Larticle analyse ses props, sa taille et sa maturité.

OpenReplay Team
OpenReplay Team
Premier aperçu de Gea, un framework UI orienté compilation

Gea est un framework UI JavaScript orienté compilation : un plugin Vite lit votre JSX pendant le build, détermine quels nœuds du DOM dépendent de quel état, et émet des patchs DOM directs. Il n’y a pas de DOM virtuel et aucun diff n’est effectué à l’exécution.

Les frameworks qui promettent de compiler le runtime jusqu’à le faire disparaître apparaissent tous les quelques mois, et le billet de lancement se contente généralement de présenter l’argumentaire et les chiffres, sans grand-chose sur les compromis. Les pages de Gea se lisent à peu près de la même manière ; ce qui suit expose donc le modèle tel que le projet le décrit, précise d’où vient chaque chiffre, et examine de près le seul point qui diffère réellement de React et Vue : les props objets bidirectionnelles.

À retenir

  • Gea câble la réactivité au moment de la compilation : un plugin Vite analyse le JSX, associe l’état aux nœuds du DOM, et émet des patchs ciblés au lieu d’embarquer un DOM virtuel.
  • Le modèle tout entier tient en trois règles : les stores sont des classes qui étendent Store, les composants sont des classes dotées d’une méthode template() ou de simples fonctions, et les valeurs calculées sont des getters.
  • Une prop de type objet ou tableau transmet à l’enfant le proxy même que détient le parent : une écriture dans l’enfant modifie donc aussi l’état du parent. Les primitives, elles, sont copiées.
  • Le projet annonce 121 o en brotli pour un hello world, 4,9 ko pour une todo interactive, et un score de 1,02 au js-framework-benchmark, mesures effectuées sur Gea 1.3.0 par le mainteneur, à partir de ses propres builds.
  • Avec un seul mainteneur, un numéro de version encore précoce et aucune revue indépendante, Gea mérite un prototype d’un après-midi plutôt qu’un pari en production.

Qu’est-ce que Gea ?

Gea déplace la réactivité du runtime vers le build. D’après le site du projet, son plugin Vite lit votre JSX à la compilation, détermine quels nœuds du DOM dépendent de quelles portions d’état, et met en place des patchs qui ne touchent que ces nœuds. La comparaison avec Vue formule le contraste sans détour : là où Vue réexécute une fonction de rendu et compare l’arbre obtenu, Gea se contente d’exécuter les fonctions de patch que le compilateur a déjà générées. Votre état réside dans de simples classes que Gea enveloppe dans un proxy profond ; une affectation ordinaire comme this.count++ suffit donc à faire bouger le DOM. Il n’y a rien à envelopper ni de liste de dépendances à maintenir à jour. Le README présente cette filiation comme le prolongement des bibliothèques erste.js et regie du mainteneur, désormais dotées de transformations JSX à la compilation.

Le modèle de Gea en trois lignes

Toute la surface d’API de Gea tient en trois règles : les stores sont des classes qui étendent Store, les composants sont des classes dotées d’une méthode template() ou de simples fonctions, et les valeurs calculées sont de simples getters. Le compteur du README illustre l’ensemble :

// 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>
    )
  }
}

La documentation des composants explique que le plugin Vite réécrit les composants fonctions en composants classes pendant le build, et que le template d’un composant ne s’exécute qu’une seule fois. Tout ce qui suit relève du patch, non du re-rendu.

En quoi le JSX de Gea diffère-t-il de celui de React ?

Le JSX de Gea ressemble à celui de React, et une seule convention doit véritablement changer : écrivez class là où React attend className. Les événements sont plus permissifs. Le README les écrit sous forme d’attributs en minuscules comme click, input et change, mais la comparaison avec Vue dans la documentation confirme que onClick, onInput et onChange sont également acceptés : les gestionnaires à la mode React se transposent donc tels quels. Et ref ne prend pas d’objet ref : Gea place directement le nœud DOM sur la propriété du composant une fois le rendu terminé.

// Habitude React      // Équivalent Gea
<div className="card"   <div class="card"
  onClick={save} />       click={save} />

Le motif ref de la documentation consiste en un champ de classe initialisé à null, ref={this.videoEl} sur l’élément, puis l’utilisation directe de this.videoEl après le rendu.

Props : les objets sont le proxy du parent

L’écart le plus marqué avec React et Vue tient à ce qu’il advient d’une prop non primitive. La documentation des composants de Gea explique que l’enfant reçoit exactement le même proxy que celui détenu par le parent : toute écriture effectuée par l’enfant atterrit donc dans l’état du parent et se répercute dans le DOM du parent. Les primitives se comportent comme les arguments de fonction en JavaScript : l’enfant en reçoit une copie, et la réaffecter ne change rien en dehors de l’enfant. La documentation montre un enfant faisant précisément cela :

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>
  }
}

La règle tient quelle que soit la profondeur de l’arbre. Transmettez la même référence à un petit-enfant, laissez-le écrire dans l’objet, et tous les ancêtres qui observent ces données sont redessinés. Rien n’a besoin d’être remonté via un callback, et il n’y a ni emit ni v-model en intermédiaire.

Mise à jour du parent par l’enfantReactVueGea
Objets/tableauxProps callbackemit / v-modelMutation directe du proxy partagé
PrimitivesProps callbackemit / v-modelImpossible (passage par valeur)

La documentation ne présente cela que comme un avantage, et les questions ouvertes restent sans réponse. Dans un arbre de 40 composants, quel composant a muté cet objet ? La convention unidirectionnelle de React existe en partie pour que les changements aient une origine traçable ; Gea troque cela contre la simplicité directe, et personne n’a encore documenté le coût de ce compromis à grande échelle. Il en va de même pour le câblage à la compilation lui-même : la façon dont le compilateur traite le code qu’il ne peut pas analyser statiquement n’est pas abordée par la documentation.

Taille et vitesse, telles que le projet les rapporte

Chaque chiffre de performance concernant Gea provient des mesures du projet lui-même, comparées aux builds réalisés par le mainteneur pour les frameworks concurrents. Les tableaux de taille du README situent une application hello world à 121 o de JavaScript brotli, face aux builds du projet pour Solid (3,6 ko), Svelte (8,5 ko), Vue (20,7 ko) et React (50,8 ko), la todo interactive s’établissant à 4,9 ko. Les deux séries de chiffres ont été relevées sur Gea 1.3.0 à partir de builds de production Vite 8.0.10 fraîchement générés.

Le score de 1,02 au js-framework-benchmark, où 1,00 correspond à du JavaScript natif écrit à la main, provient de l’exécution de la suite par le projet lui-même sur Chrome 147, et non d’une campagne officielle publiée. La mention « framework UI compilé le plus rapide » sur la page d’accueil est une affirmation du projet fondée sur ces mêmes chiffres auto-mesurés, et non sur un constat émanant d’un tiers.

Qu’est-ce qui est livré avec Gea ?

Le tableau des paquets du README liste @geajs/core, @geajs/vite-plugin, @geajs/ssr pour le rendu côté serveur, create-gea pour l’échafaudage, ainsi que @geajs/ui (composants headless bâtis sur Zag.js) et @geajs/mobile pour les primitives mobiles. gea-tools est une extension VS Code et Cursor, et non un paquet npm.

L’entrée la plus inhabituelle concerne l’outillage IA. L’exécution de npx skills add dashersw/gea installe un ensemble de compétences d’agent hébergées dans le dépôt sous .cursor/skills/gea-framework, qui fournissent à un assistant de codage IA les conventions qu’il devrait sinon deviner : le fonctionnement des stores, la manière de déclarer les composants, et les particularités du JSX. Pour un jeune framework sur lequel aucun modèle ne dispose de données d’entraînement, livrer les conventions sous forme de compétences consommables par l’éditeur est un choix d’accueil pragmatique.

Maturité : ce que les numéros de version révèlent

Les tableaux de comparaison et de taille du README ont été mesurés sur Gea 1.3.0, et @geajs/core a depuis publié la version 1.4.0 d’après les notes de version du projet. Gea est sous licence MIT et maintenu par une seule personne, Armagan Amcalar. Tous les chiffres de benchmark et de taille sont auto-déclarés, et aucune revue technique indépendante du framework n’existe à ce jour. Pour une équipe, la conclusion est simple : le modèle est cohérent et suffisamment restreint pour être évalué en un après-midi, mais un mainteneur unique, un numéro de version précoce et des chiffres non vérifiés signifient qu’il n’existe encore aucune base factuelle pour y engager un produit.

L’affirmation véritablement intéressante de Gea n’est pas la taille du bundle ; c’est que de simples classes, fonctions et getters peuvent porter un modèle de réactivité complet dès lors qu’un compilateur en assure le câblage. Le moyen le plus rapide d’évaluer cette affirmation consiste à échafauder le compteur et l’exemple de props ci-dessus, puis de juger si la sémantique bidirectionnelle des objets relève de la clarté ou du handicap de débogage dans votre type de base de code.

FAQ

En quoi Gea diffère-t-il de Solid et Svelte ?

Les trois s'appuient sur un compilateur, mais la primitive réactive diffère. Solid construit sa réactivité sur des signals qui s'exécutent dans le navigateur, et Svelte 5 utilise sa syntaxe de runes compilée depuis son propre langage de templates. Gea n'a ni l'un ni l'autre : l'état est détenu dans de simples classes enveloppées par un proxy profond, et un plugin Vite lit du JSX standard au moment du build pour câbler des patchs DOM directs.

Quels hooks de cycle de vie les composants Gea proposent-ils ?

Les composants classes de Gea exposent quatre hooks. created(props) se déclenche entre le constructeur et le premier rendu, et c'est là que la documentation place la logique d'initialisation. onAfterRender() s'exécute une fois que l'élément du composant se trouve dans le document et que ses enfants sont montés. onAfterRenderAsync() attend le prochain requestAnimationFrame. dispose() retire le composant du DOM et démonte ses observateurs et ses enfants. La documentation oriente vers les composants classes dès que l'un de ces hooks est nécessaire.

Gea fonctionne-t-il avec TypeScript ?

Oui. Un composant classe déclare la forme de ses props avec « declare props », une déclaration ambiante qui n'émet aucun JavaScript mais permet à tout éditeur compatible TypeScript de compléter et de vérifier les attributs, sans plugin de framework. Annoter le paramètre de template() avec this['props'] propage ces types dans les variables déstructurées à l'intérieur de la méthode ; sans cela, elles retombent sur any. Les composants fonctions bénéficient du même traitement via une annotation de paramètre classique.

Comment démarrer un nouveau projet Gea ?

Échafaudez-en un avec « npm create gea@latest », l'outil create-gea du projet. Les builds Gea reposent sur Vite, et c'est @geajs/vite-plugin qui prend en charge la transformation JSX, le câblage de la réactivité et le rechargement à chaud. La documentation inclut également un guide d'utilisation dans le navigateur pour exécuter Gea sans étape de build, aux côtés de guides pour le routeur, le kit UI et les paquets mobiles.

DevTools for the frontend

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

We use cookies to improve your experience. By using our site, you accept cookies.