JSX / code-first UI

  • UI structure is expressed as code, e.g. return <div>{thing}</div> .

Ripple

  • Ripple

  • Origin:

    • 2024/2025.

  • What it is:

    • A TypeScript-first, component-based UI framework. It combines ideas from React, Solid, and Svelte, with its own .tsrx  component format/compiler.

  • UI syntax:

    • JSX-like markup.

  • Main idea:

    • Fine-grained reactivity + compiler-driven UI + TypeScript-native authoring. It tries to get the directness of Solid, the compiler approach of Svelte, and the familiar component model of React, while keeping the UI syntax close to JSX.

  • Has virtual DOM:

    • No.

  • Reactivity:

    • Fine-grained. The current API is track() .

Examples
  • Button increases a counter :

import { track } from "ripple";

const Counter = () => {
  let &[count] = track(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => count++}>
        Increment
      </button>
    </div>
  );
};

Qwik

  • Origin:

    • 2021, from the author of Inferno, who also worked on React and Svelte.

  • What it is:

    • Resumable UI framework

    • Focuses in SSR/startup performance.

    • Client JS is aggressively lazy-loadable.

    • The programming model is more framework-specific.

  • UI syntax:

    • JSX.

  • Main idea:

    • Don't hydrate; resume.

  • Has virtual DOM:

    • No.

  • Reactivity:

    • Fine-grained/resumable.

Examples
  • Button increases a counter :

import { component$, useSignal } from 'https://esm.sh/@builder.io/qwik';
import { render } from 'https://esm.sh/@builder.io/qwik';

export const Counter = component$(() => {
  const count = useSignal(0);

  return (
    <div>
      <p>Count: {count.value}</p>
      <button onClick$={() => count.value++}>Increment</button>
    </div>
  );
});

render(document, <Counter />);

Solid

  • Origin:

    • 2018-ish, 1.0 in 2021.

  • What it is:

    • Reactive UI framework.

  • UI syntax:

    • JSX.

  • Main idea:

    • Fine-grained reactivity.

    • Kinda like React, but with a Svelte-like compiler

    • "A more well thought-out and faster version of React".

  • Has virtual DOM:

    • No.

  • Reactivity:

    • Fine-grained signals

Examples
  • Button increases a counter :

import { createSignal } from "solid-js";
import { render } from "solid-js/web";

const Counter = () => {
  const [count, setCount] = createSignal(0);

  return (
    <div>
      <p>Count: {count()}</p>
      <button onClick={() => setCount(count() + 1)}>
        Increment
      </button>
    </div>
  );
};

render(() => <Counter />, document.getElementById("app"));
  • Ex2 :

import { For, Show } from "solid-js";

export default function List(props) {
  return (
    <Show when={props.items.length} fallback={<div>No items</div>}>
      <ul>
        <For each={props.items}>{item => <li>{item.title}</li>}</For>
      </ul>
    </Show>
  );
}
import { For } from "solid-js";

export default function Users(props) {
  return <ul><For each={props.users}>{u => <li>{u.name}</li>}</For></ul>;
}

Inferno

  • .

Preact (Has VDOM)

  • Origin:

  • What it is:

    • Library, React-compatible.

  • UI syntax:

    • JSX.

  • Main idea:

    • React API with tiny footprint

  • Has virtual DOM:

    • Yes.

  • Reactivity:

    • Component re-execution.

Examples
  • Button increases a counter :

import { render } from "preact";
import { useState } from "preact/hooks";

const Counter = () => {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        Increment
      </button>
    </div>
  );
};

render(<Counter />, document.getElementById("app"));

React (Has VDOM)

  • Origin:

    • Facebook, 2013.

  • What it is:

    • Library.

  • UI syntax:

    • JSX.

  • Main idea:

    • Component model + React ecosystem

  • Has virtual DOM:

    • Yes.

  • Reactivity:

    • Component re-execution

  • AJAX:

    • Via fetch , Axios, or libraries like React Query; client-side rendering is driven by async data.

Asynchronous Behavior
  • React doesn’t fundamentally change how concurrency works—JS is still single-threaded—but it improves ergonomics and state management around asynchronous operations

  • React doesn’t add new concurrency primitives—it doesn’t give JS threads, parallelism, or async I/O that didn’t exist.

  • Everything React does is built on native JS: Promises, the event loop, fetch , timers, etc.

  • Automatic DOM diffing  â†’ no manual innerHTML  manipulation.

    • Your component re-renders automatically when state changes.

    • In Vanilla JS :

      fetch("/data")
        .then(res => res.text())
        .then(html => document.getElementById("widget").innerHTML = html);
      
      • You must track which element corresponds to which data.

      • Any additional async operations updating the same element require careful coordination.

    • In React :

      const [data, setData] = useState(null);
      
      useEffect(() => {
        fetch("/data")
          .then(res => res.text())
          .then(setData);
      }, []);
      
      return <div>{data || "Loading..."}</div>;
      
      • React automatically re-renders the component when state changes.

      • No manual DOM manipulation.

      • Concurrency conflicts are minimized because state updates are batched and applied in order.

Examples
  • Button increases a counter :

import { useState } from "react";
import { createRoot } from "react-dom/client";

const Counter = () => {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        Increment
      </button>
    </div>
  );
};

createRoot(document.getElementById("app")).render(<Counter />);
  • Simple async behavior :

function Component() {
  const [data, setData] = React.useState(null);

  React.useEffect(() => {
    fetch("/data")
      .then(res => res.json())
      .then(setData);
  }, []);

  return <div>{data}</div>;
}
  • More complex async behavior :

    function Dashboard() {
      const [widgets, setWidgets] = React.useState([]);
      const [loaded, setLoaded] = React.useState(false);
    
      React.useEffect(() => {
        Promise.all([
          fetch("/data1").then(r => r.text()),
          fetch("/data2").then(r => r.text()),
          fetch("/data3").then(r => r.text()),
        ])
          .then(results => setWidgets(results))
          .finally(() => setLoaded(true));
      }, []);
    
      return (
        <div>
          {widgets.map((w, i) => (
            <div key={i}>{w || "Loading..."}</div>
          ))}
          {loaded && <div>Dashboard loaded</div>}
        </div>
      );
    }
    

Stencil

  • Origin:

  • What it is:

    • Web Components compiler

  • UI syntax:

    • JSX.

  • Main idea:

    • Compile JSX → Web Components

  • Has virtual DOM:

    • Compile-time/runtime machinery

  • Reactivity:

    • Component/state updates

Examples
  • Button increases a counter :

import { Component, State, h } from "@stencil/core";

@Component({
  tag: "my-counter",
})
export class Counter {
  @State() count = 0;

  render = () => (
    <div>
      <p>Count: {this.count}</p>
      <button onClick={() => this.count++}>
        Increment
      </button>
    </div>
  );
}

Mithril

  • Origin:

  • What it is:

    • Small UI framework

  • UI syntax:

    • m()  / JSX.

  • Main idea:

    • Small, self-contained MVC-ish UI

  • Has virtual DOM:

    • Yes.

  • Reactivity:

    • VDOM redraw

Examples
  • Button increases a counter :

import m from "mithril";

const Counter = {
  count: 0,

  view: () => (
    m("div", [
      m("p", `Count: ${Counter.count}`),
      m(
        "button",
        { onclick: () => Counter.count++ },
        "Increment"
      )
    ])
  )
};

m.mount(document.getElementById("app"), Counter);