Back

Ripple: 注目すべき新しいTypeScript UIフレームワーク

Ripple: 注目すべき新しいTypeScript UIフレームワーク

ReactのuseMemouseCallback、そしてクロージャのバグと格闘した経験があれば、リアクティビティを手動で管理することに伴う精神的なオーバーヘッドをすでにご存知でしょう。Dominic Gannaway氏(React Hooksコントリビューター、Infernoの作者、Svelte 5のコアメンテナー)が開発した新しいTypeScriptフレームワークRippleは、まったく異なるアプローチを採用しています。リアクティビティをコンパイル時に処理し、残りはフレームワークに任せるのです。

技術的に興味深いポイントを見ていきましょう。

重要なポイント

  • Rippleはコンパイラ駆動型のUIフレームワークで、.rippleファイルを使用し、きめ細かいDOM更新ロジックを生成します。仮想DOMや差分検出は不要です。
  • そのリアクティビティモデルはtrack()@アクセス演算子を中心としており、依存配列、useMemouseCallbackが不要になります。
  • リアクティブコレクション(#[]#{})は、UI更新を自動的にトリガーする直接的なミューテーションを可能にします。
  • このフレームワークは充実した開発者ツール(Vite統合、VSCode拡張機能、スコープ付きスタイル)を提供していますが、まだ初期段階の実験的なものです。学習する価値はありますが、本番環境での使用にはまだ準備が整っていません。

Ripple UIフレームワークとは?

Rippleは、.rippleファイルを中心に構築されたコンパイラ駆動型のUIフレームワークです。.ripple.tsx.jsxとは異なる独自のモジュール形式です。Rippleは実行時に仮想DOMや差分アルゴリズムを提供する代わりに、コンパイラがコンポーネントを解析し、実行時に動作するきめ細かいDOM更新ロジックを生成します。

差分検出はありません。コンポーネントの再実行もありません。変更されたノードだけに対する外科的な更新のみです。

その結果、Rippleは概念的にSolid(きめ細かいシグナル)とSvelte(コンパイラ駆動型の出力)の中間に位置するフレームワークとなっていますが、TypeScriptを最初から第一級市民として扱っています。後付けではありません。

Rippleのきめ細かいリアクティビティの仕組み

Rippleのきめ細かいリアクティビティモデルは、2つのプリミティブを中心としています。

  • track() — リアクティブな値または派生計算を作成
  • @ — 追跡された値の読み書きのためのアクセス演算子
import { track } from 'ripple'

export component Counter() {
  let count = track(0)
  let double = track(() => @count * 2) // 自動派生、依存配列不要

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

@countが変更されると、それに依存するDOMノードのみが更新されます。doubleは自動的に再計算されます。useMemoも依存配列もデバッグすべきクロージャのバグもありません。

これはReactのモデルとは大きく異なります。Reactでは状態変更がコンポーネント全体の再実行をトリガーします。また、SolidのcreateSignalとも異なり、Rippleは意図的にそれを模倣していません。track()という命名は異なるメンタルモデルを示しています。シグナルグラフを手動で配線するのではなく、追跡される関係を宣言しているのです。

リアクティブコレクションについて、Rippleは#[](TrackedArray)と#{} (TrackedObject)を導入しており、直接的なミューテーションが可能です。

const todos = #[]
todos.push({ id: 1, text: 'Write docs', completed: false }) // UIが自動的に更新される

スプレッド演算子は不要です。setStateも不要です。ただミューテートして進めるだけです。

Ripple TSフロントエンドフレームワークの開発者体験

Rippleは焦点を絞った実用的なツールストーリーを提供しています。

  • CLIスキャフォールディング: npm create ripple my-appで数秒でViteベースのプロジェクトを作成
  • VSCode拡張機能: .rippleファイル内でのIntelliSense、診断、エラーハイライト
  • PrettierとESLintサポート: .rippleモジュールの完全なフォーマットとリンティング
  • スコープ付きスタイル: コンポーネント内の<style>ブロックは自動的にスコープ化され、CSS Modulesのセットアップは不要

コンポーネントはfunctionの代わりにcomponentキーワードを使用し、テンプレートは戻り値ではなく文です。これはコンパイラに最適化の余地を与える微妙な変化です。

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

制御フローはプレーンなJavaScriptを使用します。forループ、if/elseブロック、エラーバウンダリ用のtry/catchなど、.map()の複雑な処理や<Show>ラッパーコンポーネントは不要です。

サーバーサイドレンダリングについて: Rippleのドキュメントはrender(サーバー)とhydrate(クライアント)APIに言及しているため、SSRは設計の方向性の一部です。それを取り巻くエコシステムは初期段階で進化中であり、今日本番アプリを出荷するフレームワークではありません。

まとめ

Rippleは、稀有なフレームワーク開発の経歴を持つ人物による真の技術実験です。コアアイデア — 遅延リアクティブ評価、コンパイラが所有する依存関係追跡、TypeScriptネイティブ構文 — は、たとえ本番環境でRippleコードを一行も書かなくても理解する価値があります。

興味があれば、GitHubリポジトリドキュメントが適切な出発点です。Viteスターターを立ち上げて、カウンターや小さなフォームを構築し、そのメンタルモデルがしっくりくるか確認してみてください。

興味深いフレームワークは、大声で自己主張することはほとんどありません。ただ、すでに使っているフレームワークについて違った考え方をさせてくれるだけです。

よくある質問

Reactは状態変更時にコンポーネント全体を再実行し、最適化にはuseMemoのようなフックに依存します。Solidはきめ細かいシグナルを使用しますが、手動でのシグナル作成が必要です。Rippleはコンパイラ駆動型の解析とtrack()プリミティブおよび@演算子を組み合わせて、ビルド時に外科的なDOM更新を生成し、依存配列や手動のメモ化を完全に不要にします。

いいえ。Rippleは初期段階の実験的なフレームワークです。ツールにはVite統合、VSCode拡張機能、スコープ付きスタイルが含まれていますが、エコシステムはまだ進化中です。現時点では、本番アプリケーションの出荷よりも、探索と学習に最適です。

TrackedArray (#[])とTrackedObject (#{})は、Rippleのリアクティブコレクションプリミティブです。pushやプロパティ割り当てなどの標準操作を使用してデータを直接ミューテートでき、UIが自動的に更新されます。これにより、Reactで一般的なイミュータブルな更新パターン、スプレッド演算子、setStateコールが不要になります。

Rippleのドキュメントはrenderとhydrate APIに言及しており、SSRがフレームワークの設計方向の一部であることを示しています。ただし、SSRのストーリーはまだ初期段階です。Next.jsやSvelteKitに匹敵する成熟したメタフレームワークや本番環境でテストされたSSRパイプラインは、まだ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