- Snap(スナップチャット)が開発した Valdi は、iOS、Android、macOS で ネイティブ性能 を提供する クロスプラットフォームUIフレームワーク で、宣言的な TypeScript で記述した UI を各プラットフォームのネイティブビューへ直接コンパイルする
- WebView や JavaScript ブリッジなしで 動作し、自動ビュー再利用、最適化されたレイアウトエンジン、ビューポートベースのレンダリング などにより高い性能を維持する
- 即時ホットリロード、VSCode デバッグ、TSX 構文対応 などにより開発速度を高め、既存のネイティブアプリとの統合 も柔軟に支援する
- TypeScript とネイティブコード間の型安全なバインディング、protobuf 対応、C++・Swift・Kotlin 連携 などにより深いネイティブ統合構造を提供する
- 8年間にわたり Snap の本番アプリで検証された技術 であり、大規模なアニメーション・ジェスチャー・マルチスレッド処理などの高度な機能を含む 拡張可能な UI 開発基盤 である
Valdi の概要
- Valdi は Snap が 8年間本番アプリで使用してきた クロスプラットフォームUIフレームワーク
- 宣言的な TypeScript で UI を記述すると、iOS、Android、macOS の ネイティブビューへ直接コンパイル される
- WebView や JavaScript ブリッジなしで ネイティブ性能を提供する
- 現在は ベータ段階 であり、オープンソース環境でのツールとドキュメントの安定化が完了すれば正式版へ移行する予定
主な特徴と例
- 基本コンポーネントの例では
HelloWorld クラスで と を使ってシンプルな UI を構成
- TypeScript ベースの 宣言的コンポーネント構造 を採用しており、各プラットフォームで同一コードを実行可能
- 公式ドキュメント、インストールガイド、API リファレンス、Codelab などの開発資料を提供
性能最適化
- ネイティブ性能 を確保するため、次のような構造を採用
- 自動ビュー再利用: グローバルなビュープーリングシステムにより画面間でビューを再利用し、インフレーション遅延を最小化
- 独立コンポーネントレンダリング: 親レンダリングに影響されず、個別コンポーネントのみ更新
- C++ ベースのレイアウトエンジン: メインスレッドで最小限のオーバーヘッドで動作
- ビューポート認識レンダリング: 画面に見えているビューのみをインフレートし、無限スクロール性能を向上
- 関連資料として Performance Optimization Guide を提供
開発者体験
- ホットリロード 機能により、コード変更後すぐに反映
- VSCode デバッグ対応: ブレークポイント設定、変数の確認、性能プロファイリング、ヒープダンプ取得が可能
- TSX 構文と型安全性 により、親しみやすい開発環境を提供
柔軟な統合構造
- 既存のネイティブアプリに Valdi を組み込み 可能 (
Embed Valdi in native)
- Valdi 内でネイティブビューを使用 可能 (
Embed native in Valdi)
- Polyglot モジュール を通じて C++、Swift、Kotlin、Objective-C コードと型安全に連携
- フルスタックアーキテクチャ により、バックグラウンドワーカースレッドを活用した全機能実装が可能
ネイティブ統合
- 自動コード生成 により、TypeScript インターフェースを Kotlin、Objective-C、Swift バインディングへ変換
- Polyglot モジュール を通じてプラットフォーム API およびサードパーティ製ネイティブライブラリへ直接アクセス
- 双方向通信 により、複雑なデータ構造やコールバックを安全にやり取り可能
- protobuf 対応 により、効率的なデータシリアライズが可能
実証済みの安定性と機能
- Snap の主要な本番機能を支える中核技術
- 高度なアニメーション、リアルタイムレンダリング、複雑なジェスチャーシステム をサポート
- Flexbox レイアウト、マルチスレッドワーカー、ネイティブアニメーション、高度なジェスチャー認識、組み込みテストフレームワーク、Bazel 統合ビルド など多様な機能を含む
サポートとライセンス
- Discord コミュニティ を通じたサポートを提供
- MIT ライセンス で公開されており、自由に利用・貢献可能
2件のコメント
Hacker Newsの意見
うちの会社では React Native を使っているが、アプリストアやプラットフォームごとの言語差異がなくなることを切望している。
来年は、基本的にWebサイトベースにして、モバイルアプリは WebView で包み、通知・GPS・HealthKit のような機能だけをネイティブコードで処理することを検討している。
最近は AI のおかげで、各プラットフォームごとにUIを別々に作るほうがむしろ良いのではないかと思うこともある。
重要なのは、UIコンポーネントをあまり独特にしすぎず、ボタンのスタイルやバックスタックのような部分だけをプラットフォームごとに少し調整することだ。
また、Service Worker でオフライン機能を追加し、ネットワーク診断ツールをアプリ起動時に実行して問題を素早く把握できるようにした。
ただし、私のアプリはB2B向けなので、こうした構成が可能だった。
Web はもともとアプリストアやコード署名を回避するための道だと思っている。
ほとんどの機能はWebでも実現できるし、HealthKit だけ別のコンパニオンアプリで処理すればよい。
マーケティング予算でQRコードやリンクを宣伝するほうが、アプリストア競争よりはるかに効率的かもしれない。
特にiOSで「戻るスワイプ」が効かない瞬間、それが WebView だとすぐ分かる。
私はビジネスUIを一度書き、LLMで React Native と React の間を変換している。
しかし Apple は依然として「単にWebサイトをラップしただけのアプリは却下する」という 4.2 最低機能要件 を維持している。
機能とテストを3つのプラットフォームで同期しなければならず、開発者も複数のスタックに習熟している必要がある。
ほとんどのユーザーは、よくできた WebView 実装とネイティブアプリの違いをほとんど感じないのに、その対価が大きすぎる。
Valdi は概念的に React Native と似ているように見える。
これで React ベースのクロスプラットフォームフレームワークは React Native、Lynx.js(ByteDance/TikTok)、Valdi の3つになった。
競争は良いことだが、RN ほど大きなエコシステムを素早く作れるかは疑問だ。
RN は今年、Hermesエンジンの改善、ネイティブバインディング生成器、マルチスレッドアニメーション、Tailwindサポート など多くの進展があった。
Lynx.js は React 以外のフレームワークもサポートしようとしている点で、より有利かもしれない。
RN の Radon IDE は有料だが、Valdi はオープンソースだ。
Valdi が RN の Hermesエンジン を使っている点も興味深い。
関連文書を見ると、AOT/JIT の実装方式が気になってくる。
以前 Snap でこのプロジェクトの初期バージョン(Screenshop!)を一緒にデバッグしていたことがある。
Simon は素晴らしいエンジニアで、このプロジェクトが公開されたのは本当にうれしい。
Snap チームに祝意を送りたい。
カメラ、AR、通知、スクリーンショット検知など、ネイティブ統合が重要なアプリだからなおさら驚きだ。
それがこうして現実になったのはうれしい。
本当に頭の切れる人で、チーム全体に祝福を送りたい。
Snapchatが作ったUIフレームワーク に Discordコミュニティ とは、個人的にはまったく魅力を感じない。
完璧ではないが、将来の流れから自分で外れてしまうことになるのかもしれない。
文書には「C++、Objective-C、Kotlin オブジェクトを TypeScript に公開すると Native Reference、逆は JS Value Reference」と書かれているが、
Swift や SwiftUI への言及がない点 は少し気がかりだ。
正直、Snap が作ったフレームワークは信頼しにくい。
昔の Androidアプリ品質 があまりにも悪かったからだ。
Valdi は「TypeScript で一度書けば、iOS、Android、macOS でネイティブ性能で動作するUIフレームワーク」と紹介されている。
WebView や JS ブリッジがない点を強調している。
それぞれのプラットフォームの ネイティブ言語でUIを2回書き、共通ロジックは C 系 FFI で共有すればいいと思う。
そんなに難しいことだろうか?
チームの大半は Android ユーザーだが、顧客は iOS 中心なので優先順位をそうしている。
RN アプリを作った経験はあるが、それでも 本当に魔法のようなクロスプラットフォームソリューション を期待している。
そうすれば、Web、モバイル、デスクトップ、CLI などさまざまなインターフェースが、単にコアを呼び出す薄いレイヤーになる。
完全に一貫したUXは難しいだろうが、長期的には 3rd-party フレームワーク依存 を減らせる。
Valdi の 状態管理方式 が気になるなら、React のクラスコンポーネントスタイルをそのまま使っている。
公式文書の例を見ると、
StatefulComponentを継承してonCreate、onDestroy、onRenderを実装する構造だ。今のように何十個もの
useFunctionを使う方式は、エラーが多く複雑だ。残念ながら Linux、Windows、HTML ターゲット には対応していない
RNでは、ほとんどのアプリのビジネスロジックは JS だけでも十分高速に動かせます。
ただ、磨き込んでいくと「プラットフォームごとに動作が異なる場合が多い」ため、そこで答えが出ないほど難しくなるのが問題だと思います。