はじめに
個人的に、Rustでフロントエンド開発ができるようになったのは結構大きな変化だと思っています。
TypeScriptやJavaScriptでReactを書くのは楽しいんですが、型安全性とか実行時エラーの少なさという点では、やっぱりRustに軍配が上がる。でも「RustでUI書くのって大変そう」というイメージがあって、なかなか手が出なかったんですよね。
そこで今回紹介するのがDioxus(ディオクサス)。これ、RustでReactライクなコードを書けるフレームワークで、しかもWeb、デスクトップ、モバイルを単一コードベースで開発できるという、かなり欲張りなやつです。
GitHubスターは32,000を超えていて、FutureWeiやGitHubアクセラレータプログラムの支援も受けている本格的なプロジェクトです。
Dioxusとは
Dioxusは「One codebase, every platform」をコンセプトにした、Rust製のフルスタックUIフレームワークです。
Reactを書いたことがある人なら、見た瞬間に「あ、これ書ける」と思うはず。JSXに似たrsx!マクロを使って、宣言的にUIを記述できます。
対応プラットフォームが幅広いのも特徴で、Webアプリ(WASM)、デスクトップアプリ(Windows/macOS/Linux)、モバイルアプリ(iOS/Android)、さらにはTUIまでカバーしています。
AirbusやESA、Y Combinatorのスタートアップでも採用されているという話で、実績も十分です。
特徴・メリット
Reactライクな開発体験
正直なところ、これが一番のポイントですね。Rustの学習コストは高いですが、UIの書き方自体はReactに慣れていれば違和感なく入れます。
fn app() -> Element {
let mut count = use_signal(|| 0);
rsx! {
h1 { "カウンター: {count}" }
button { onclick: move |_| count += 1, "増やす" }
}
}
use_signalはReactのuseStateに相当するもので、状態管理の考え方もほぼ同じ。React、Solid、Svelteの良いところを組み合わせたシグナルベースの設計になっています。
爆速ホットリロード
これ、意外と重要なんですよ。Rustってコンパイル遅いイメージがありますが、Dioxusはマークアップやスタイルの変更がミリ秒単位で反映されます。
開発中に「ちょっとここの色変えたい」みたいな微調整を繰り返すとき、この速さは本当にありがたい。時短になるし、開発のリズムが崩れません。
単一コードベースでマルチプラットフォーム
Web版を作ったら、ほぼ同じコードでデスクトップ版も出せる。これ、個人開発者にとってはかなりコスパが良い話です。
Electronと違って、最終的なバイナリサイズもコンパクト。Webアプリは50KB未満、デスクトップ・モバイルアプリは5MB未満に収まるそうです。
フルスタック対応
バックエンドフレームワークのAxumと深く統合されていて、サーバーサイドレンダリング、WebSocket、Server-Sent Eventsなども扱えます。
フロントエンドだけじゃなく、APIサーバーまで全部Rustで書けるというのは、型の一貫性という意味でもメリットが大きいですね。
ゼロコンフィグで始められる
CLIツールが優秀で、プロジェクト作成からビルド、デプロイまで面倒を見てくれます。設定ファイルをゴリゴリ書く必要がないのは、30代になって思うのは、こういう「すぐ動く」体験が本当に大事だなということ。
インストール方法
まずRustがインストールされていることが前提です。
Dioxus CLIのインストール
# cargo-binstallを使う場合(推奨・高速)
cargo binstall dioxus-cli
# 通常のcargoインストール
cargo install dioxus-cli
# 最新版をGitから直接
cargo install --git https://github.com/DioxusLabs/dioxus dioxus-cli --locked
プロジェクトの作成
# 新規プロジェクト作成
dx new my-app
# プロジェクトディレクトリに移動
cd my-app
# 開発サーバー起動
dx serve
これだけで、ホットリロード対応の開発サーバーが立ち上がります。
基本的な使い方
プロジェクト構成
my-app/
├── Cargo.toml
├── Dioxus.toml
└── src/
└── main.rs
シンプルなカウンターアプリ
use dioxus::prelude::*;
fn main() {
dioxus::launch(app);
}
fn app() -> Element {
let mut count = use_signal(|| 0);
rsx! {
div {
class: "container",
h1 { "Dioxus カウンター" }
p { "現在の値: {count}" }
button {
onclick: move |_| count += 1,
"増やす"
}
button {
onclick: move |_| count -= 1,
"減らす"
}
}
}
}
コンポーネントの分割
#[component]
fn Counter(initial: i32) -> Element {
let mut count = use_signal(|| initial);
rsx! {
div {
p { "カウント: {count}" }
button { onclick: move |_| count += 1, "+" }
button { onclick: move |_| count -= 1, "-" }
}
}
}
fn app() -> Element {
rsx! {
Counter { initial: 0 }
Counter { initial: 100 }
}
}
非同期処理
fn app() -> Element {
let future = use_resource(|| async {
reqwest::get("https://api.example.com/data")
.await
.unwrap()
.json::<serde_json::Value>()
.await
.unwrap()
});
rsx! {
match &*future.read_unchecked() {
Some(data) => rsx! { pre { "{data:#?}" } },
None => rsx! { p { "読み込み中..." } }
}
}
}
ビルドコマンド
# Web向けビルド
dx build --release --platform web
# デスクトップ向けビルド
dx build --release --platform desktop
# バンドル(配布用)
dx bundle --release
実践的なユースケース
社内ツールのデスクトップアプリ化
これは一択ですね。Webアプリとして作ったものを、そのままデスクトップアプリとして配布できます。Electronより軽量で、ネイティブに近いパフォーマンスが出せます。
型安全なフルスタックアプリ
フロントエンドからバックエンドまで全部Rustで書けるので、APIの型定義を共有できます。「フロントとバックで型がズレてバグった」みたいな悲しい事故を防げます。
パフォーマンス重視のWebアプリ
WASM経由でブラウザ上で動くので、計算量の多い処理をRustの速度で実行できます。データ可視化やゲームなど、パフォーマンスがクリティカルな場面で真価を発揮します。
Rustの学習プロジェクト
正直なところ、Rustの入門としても悪くないです。UIという目に見える成果物があると、学習のモチベーションが維持しやすい。CLIツールで環境構築の苦労も少ないですし。
注意点
良いことばかり書いてきましたが、正直なところ注意点もあります。
Rustの学習コスト
当然ですが、Rust自体の理解は必要です。所有権やライフタイムの概念がわからないと、コンパイラに怒られまくります。ただ、Dioxus自体はその辺をうまく抽象化しているので、基本的なRustがわかれば書けます。
エコシステムの成熟度
ReactやVueと比べると、サードパーティのコンポーネントライブラリはまだ少ないです。自分で実装する場面は多くなるかもしれません。
日本語情報の少なさ
英語のドキュメントは充実していますが、日本語の情報はまだ少なめです。公式ドキュメントを読める英語力は必要になります。
まとめ
Dioxusは「RustでReactライクなUI開発を」という夢を実現してくれるフレームワークです。
- Reactに慣れていれば違和感なく書ける
- Web、デスクトップ、モバイルを単一コードベースで
- 爆速ホットリロードで開発体験も良好
- Rustの型安全性とパフォーマンスを享受できる
Rustに興味があって、フロントエンド開発もやりたいという人には、QOL上がること間違いなしです。
まずは公式サイトのチュートリアルから始めてみてください。カウンターアプリなら30分もかからず動くものが作れますし、そこから徐々に理解を深めていけます。
公式サイト: https://dioxuslabs.com GitHub: https://github.com/DioxusLabs/dioxus