Back

Ripple: Ein neues TypeScript-UI-Framework, das man im Auge behalten sollte

Ripple: Ein neues TypeScript-UI-Framework, das man im Auge behalten sollte

Wer schon einmal mit Reacts useMemo, useCallback und Stale-Closure-Bugs gekämpft hat, kennt den mentalen Overhead, der mit der manuellen Verwaltung von Reaktivität einhergeht. Ripple, ein neues TypeScript-Framework von Dominic Gannaway (React-Hooks-Contributor, Inferno-Autor, Svelte-5-Core-Maintainer), verfolgt einen völlig anderen Ansatz: Die Reaktivität wird wegkompiliert, und das Framework kümmert sich um den Rest.

Hier ist, was es technisch interessant macht.

Die wichtigsten Erkenntnisse

  • Ripple ist ein compiler-gesteuertes UI-Framework, das .ripple-Dateien verwendet und feinkörnige DOM-Update-Logik generiert – kein virtuelles DOM oder Reconciliation erforderlich.
  • Sein Reaktivitätsmodell basiert auf track() und dem @-Zugriffsoperator, wodurch Dependency-Arrays, useMemo oder useCallback überflüssig werden.
  • Reaktive Collections (#[] und #{}) ermöglichen direkte Mutationen, die automatisch UI-Updates auslösen.
  • Das Framework bietet solides Developer-Tooling (Vite-Integration, VSCode-Extension, Scoped Styles), bleibt aber ein Experiment im Frühstadium – zum Studieren geeignet, noch nicht produktionsreif.

Was ist das Ripple-UI-Framework?

Ripple ist ein compiler-gesteuertes UI-Framework, das auf .ripple-Dateien basiert – einem eigenen Modulformat, das sich von .tsx oder .jsx unterscheidet. Anstatt ein virtuelles DOM und einen Diffing-Algorithmus zur Laufzeit auszuliefern, analysiert Ripples Compiler die Komponenten und generiert feinkörnige DOM-Update-Logik, die zur Laufzeit ausgeführt wird.

Keine Reconciliation. Keine Komponenten-Neuausführungen. Nur chirurgisch präzise Updates genau der Knoten, die sich geändert haben.

Das Ergebnis ist ein Framework, das konzeptionell zwischen Solid (feinkörnige Signals) und Svelte (compiler-gesteuerter Output) liegt, bei dem TypeScript von Grund auf als erstklassiger Bestandteil behandelt wird – nicht nachträglich hinzugefügt.

Wie Ripples feinkörnige Reaktivität funktioniert

Ripples feinkörniges Reaktivitätsmodell basiert auf zwei Primitiven:

  • track() – erstellt einen reaktiven Wert oder eine abgeleitete Berechnung
  • @ – der Zugriffsoperator zum Lesen und Schreiben von tracked Values
import { track } from 'ripple'

export component Counter() {
  let count = track(0)
  let double = track(() => @count * 2) // automatisch abgeleitet, kein Dependency-Array

  <div>
    <p>{@count}</p>
    <p>{@double}</p>
    <button onClick={() => @count++}>{"Increment"}</button>
  </div>
}

Wenn sich @count ändert, werden nur die DOM-Knoten aktualisiert, die davon abhängen. double wird automatisch neu berechnet. Es gibt kein useMemo, kein Dependency-Array, keine Stale Closures zum Debuggen.

Dies unterscheidet sich deutlich von Reacts Modell, bei dem Zustandsänderungen die vollständige Neuausführung von Komponenten auslösen, und von Solids createSignal, das Ripple bewusst nicht nachahmt. Die Benennung track() signalisiert ein anderes mentales Modell: Man deklariert eine tracked Relationship, anstatt einen Signal-Graph manuell zu verdrahten.

Für reaktive Collections führt Ripple #[] (TrackedArray) und #{} (TrackedObject) ein, die direkte Mutationen ermöglichen:

const todos = #[]
todos.push({ id: 1, text: 'Write docs', completed: false }) // UI aktualisiert automatisch

Keine Spread-Operatoren. Kein setState. Einfach mutieren und weitermachen.

Die Developer Experience des Ripple-TS-Frontend-Frameworks

Ripple liefert eine fokussierte, aber praktische Tooling-Story:

  • CLI-Scaffolding: npm create ripple my-app erstellt in Sekunden ein Vite-basiertes Projekt
  • VSCode-Extension: IntelliSense, Diagnostics und Error-Highlighting innerhalb von .ripple-Dateien
  • Prettier- und ESLint-Support: Vollständige Formatierung und Linting für .ripple-Module
  • Scoped Styles: <style>-Blöcke innerhalb von Komponenten werden automatisch gescoped, kein CSS-Modules-Setup erforderlich

Komponenten verwenden ein component-Keyword anstelle von function, und Templates sind Statements statt Return-Values – eine subtile Verschiebung, die dem Compiler mehr Optimierungsspielraum gibt:

component Button(props: { text: string, onClick: () => void }) {
  <button onClick={props.onClick}>{props.text}</button>
}

Control Flow verwendet einfaches JavaScript: for-Schleifen, if/else-Blöcke und try/catch für Error Boundaries – keine .map()-Gymnastik oder <Show>-Wrapper-Komponenten erforderlich.

Bezüglich Server-Side Rendering: Ripples Dokumentation verweist auf render- (Server) und hydrate- (Client) APIs, SSR ist also Teil der Design-Richtung. Das Ökosystem drumherum befindet sich im Frühstadium und entwickelt sich noch, und dies ist kein Framework, mit dem man heute eine Produktions-App ausliefern würde.

Fazit

Ripple ist ein echtes technisches Experiment von jemandem mit seltener Framework-Expertise. Die Kernideen – lazy reactive Evaluation, compiler-gesteuerte Dependency-Tracking, TypeScript-native Syntax – sind es wert, verstanden zu werden, selbst wenn man nie eine Zeile Ripple-Code für die Produktion schreibt.

Wer neugierig ist, findet im GitHub-Repo und in der Dokumentation die richtigen Einstiegspunkte. Startet den Vite-Starter, baut einen Counter oder ein kleines Formular und schaut, ob das mentale Modell anspricht.

Die interessanten Frameworks kündigen sich selten lautstark an. Sie bringen einen einfach dazu, anders über die zu denken, die man bereits verwendet.

FAQs

React führt bei Zustandsänderungen ganze Komponenten neu aus und setzt auf Hooks wie useMemo zur Optimierung. Solid verwendet feinkörnige Signals, erfordert aber manuelle Signal-Erstellung. Ripple kombiniert compiler-gesteuerte Analyse mit seinem track()-Primitiv und dem @-Operator, um chirurgisch präzise DOM-Updates zur Build-Zeit zu generieren, wodurch Dependency-Arrays oder manuelle Memoization vollständig entfallen.

Nein. Ripple ist ein experimentelles Framework im Frühstadium. Obwohl das Tooling Vite-Integration, eine VSCode-Extension und Scoped Styles umfasst, entwickelt sich das Ökosystem noch. Es eignet sich am besten zum Erkunden und Lernen, nicht zum Ausliefern von Produktions-Anwendungen.

TrackedArray (#[]) und TrackedObject (#{}) sind reaktive Collection-Primitive in Ripple. Sie ermöglichen direkte Datenmutation mit Standard-Operationen wie push oder Property-Zuweisung, und die UI aktualisiert automatisch. Dies eliminiert die Notwendigkeit für immutable Update-Patterns, Spread-Operatoren oder setState-Aufrufe, wie sie in React üblich sind.

Ripples Dokumentation verweist auf render- und hydrate-APIs, was darauf hindeutet, dass SSR Teil der Framework-Design-Richtung ist. Die SSR-Story befindet sich jedoch noch im Frühstadium. Es gibt noch kein ausgereiftes Meta-Framework oder eine produktionserprobte SSR-Pipeline vergleichbar mit Next.js oder SvelteKit für Ripple.

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. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay