Gea Framework Documentation

repository·main·Indexed 22 days ago

https://github.com/dashersw/gea

Gea is a high-performance, compiler-first reactive JavaScript UI framework that eliminates Virtual DOM overhead using build-time JSX analysis and proxy-based reactivity. It features a modular architecture including @geajs/core for reactivity and DOM patching, @geajs/ui for headless primitives, @geajs/mobile for mobile-specific components and navigation, and @geajs/ssr for server-side rendering. The ecosystem also includes a Vite plugin for JSX transforms and Gea Tools for VS Code/Cursor code intelligence.

Tokens
86K
Snippets
278
Records
449
Agent score
76%

What's inside Gea

  1. Overview of Gea core concepts

    main

    Gea is a compiler-first reactive UI framework that avoids the Virtual DOM in favor of surgical DOM patching.

    Key characteristics:

    • No Virtual DOM: The Vite plugin analyzes JSX at build time to generate targeted DOM patches.
    • Proxy-based Reactivity: You mutate state directly (e.g., this.count++) using standard JavaScript, and the framework automatically updates the DOM.
    • Just JavaScript: It uses standard classes, functions, objects, and getters instead of framework-specific primitives like signals or hooks.
    • Minimal Runtime: A basic hello-world app can ship as little as 121 B (brotli).
  2. Overview of Gea: Compiler-First Reactive UI

    main

    Gea is a compiler-first reactive UI framework designed to minimize runtime overhead by moving framework logic to the build step. Unlike traditional frameworks, Gea does not use a virtual DOM, hooks, or signals at runtime. Instead, it uses a Vite plugin to analyze JSX at build time and generate surgical DOM patches.

    Key Characteristics:

    • Zero Runtime Concepts: No signals, hooks, dependency arrays, or compiler directives. State is managed via ordinary classes (Stores), components are classes or functions, and computed values are standard JavaScript getters.
    • Proxy-Based Reactivity: State lives in classes wrapped by a deep Proxy. You can mutate properties directly (including nested objects and array methods) and the UI will update.
    • JS-Native Props: Objects and arrays passed as props are the parent's reactive proxy. Mutating these in a child component automatically updates the parent, following standard JavaScript semantics instead of requiring emit or v-model patterns.
    • Extreme Efficiency: Gea is designed to be extremely lightweight. A 'Hello World' app can be as small as 121 B (Brotli), and an interactive todo app can be ~4.9 kb (Brotli).
  3. Overview of @geajs/mobile components

    main

    The @geajs/mobile package provides several specialized components for mobile interfaces:

    • View: A full-screen component that supports transitions.
    • ViewManager: A navigation stack that handles push/pull transitions.
    • GestureHandler: Handles touch gesture recognition (tap, swipe, long tap).
    • Sidebar: A slide-out navigation panel.
    • TabView: Enables tab-based view switching.
    • NavBar: A top navigation bar.
    • PullToRefresh: Implements the pull-down-to-refresh pattern.
    • InfiniteScroll: Implements the load-more-on-scroll pattern.
  4. What is Gea?

    main

    Gea is a compiler-first reactive JavaScript UI framework designed for minimal runtime overhead. Unlike frameworks that use a Virtual DOM, Gea compiles JSX into efficient HTML string templates at build time and uses deep proxies to track state changes. It then patches only the specific DOM nodes that depend on the changed data, avoiding reconciliation overhead.

    Key characteristics include:

    • Near-zero baseline: A hello-world app ships as little as 121 B (Brotli).
    • Proxy-based reactivity: Mutate state directly and the framework handles updates automatically.
    • No framework-specific syntax: It uses standard JavaScript (classes, functions, getters, .map(), and ternaries) instead of signals, hooks, or compiler directives.
  5. Understand the Jira Clone technology stack

    main

    The Jira Clone example demonstrates the following technologies used in Gea development:

    • @geajs/core: Provides the foundation for reactive components and stores.
    • @geajs/ui: A library of pre-built UI primitives such as Dialog, Button, and Avatar.
    • Vite: Used for the development server and build tooling, integrated via @geajs/vite-plugin.
    • Tailwind CSS: Used for utility-first styling.
  6. Use Gea Tools for JSX code intelligence

    main

    Gea Tools provides code intelligence for the Gea JSX API in javascript, typescript, javascriptreact, and typescriptreact files. It supports:

    • Component completion: Suggests workspace components and built-in Gea Mobile tags (e.g., view, sidebar, tab-view, navbar, pull-to-refresh, infinite-scroll) when typing JSX tags.
    • Prop completion: Automatically suggests props based on component signatures. It recognizes props declared via parameter destructuring in template(props) (class components) or function arguments (function components), as well as const { ... } = props destructuring within the function body.
    • Event attribute completion: Suggests Gea-specific event attributes like click, input, change, keydown, blur, and submit inside JSX tags.
    • Hover details: Provides information for components, props, and event attributes.
    • Diagnostics: Warns about unknown components and uses a TypeScript plugin to suppress noisy JSX diagnostics and unused-import warnings.
  7. Organize state with multiple stores

    main

    For complex applications, split state into domain-specific stores instead of one massive store. Each store should be an independent singleton. Stores can import and interact with each other by calling methods on their respective singleton instances.

    import { Store } from '@geajs/core'
    import optionsStore from './options-store'
    import paymentStore from './payment-store'
    
    class FlightStore extends Store {
      step = 1
      boardingPass = null
    
      startOver() {
        this.step = 1
        this.boardingPass = null
        optionsStore.reset()
        paymentStore.reset()
      }
    }
    
    export default new FlightStore()
  8. How Gea reactivity and props work

    main

    Gea uses a proxy-based reactivity model that follows standard JavaScript patterns:

    • State Mutation: Mutate state directly; the framework detects the change and updates the DOM.
    • Computed Values: Use standard JavaScript getters for computed values.
    • Props: Objects and arrays passed as props are the parent's reactive proxy. If a child mutates these, the parent is also updated. Primitives are passed as copies.
    • No specialized syntax: There are no emit calls or v-model directives; data flows through standard JS object manipulation.
  9. How Computed Values work in Gea

    main

    Use standard JavaScript getters on Store classes to create derived state. The Gea Vite plugin automatically tracks which state paths are read within the template() and triggers updates when those paths change.

    class TodoStore extends Store {
      todos = []
      filter = 'all'
    
      get filteredTodos() {
        const { todos, filter } = this
        if (filter === 'active') return todos.filter(t => !t.done)
        if (filter === 'completed') return todos.filter(t => t.done)
        return todos
      }
    
      get activeCount() {
        return this.todos.filter(t => !t.done).length
      }
    }
  10. Use getters for derived state in Stores

    main

    In Gea, use standard TypeScript/JavaScript get syntax on your Store classes to create derived state. These getters re-evaluate on every access. Because the Gea Vite plugin tracks which state paths are accessed during template execution, changes to the underlying data will automatically trigger a template update, which in turn re-calls the getter to fetch the fresh value.

    import { Store } from '@geajs/core'
    
    class TodoStore extends Store {
      todos = []
      filter = 'all'
    
      get filteredTodos() {
        const { todos, filter } = this
        if (filter === 'active') return todos.filter(t => !t.done)
        if (filter === 'completed') return todos.filter(t => t.done)
        return todos
      }
    }