はじめに
お久しぶりです。私事ですが転職しました。いや、気がつけば会社が傾いて逃げ出してから10数年、フリーランスとして生きてきましたが、年を取り体力が落ち、集中力が落ち、学習速度が落ち、技術への感度が落ち、って落ち続けこのまま技術を切り売りする社会の底辺で生き延びられる自信が持てませんでした。そんなわけで自分より若い人たちの会社に入れてもらい、頑張ってる人たちをぜーはー言いながら追いかける場所に身を置かせていただくことにしました。複数の顧客と案件抱えて右往左往するのに慣れていないこともあって、想定より仕事が忙し目で割とへばっていますが、倒れない程度にがんばります。
さて、いきなりどうでも良いことから入りましたが、今年も始まりましたSlint Advent Calendar!昨日までは @task_jp さんによるこの1年のslintの更新についてのご紹介でした。
本日はSlintって他のGUIフレームワークと比べてどうなのという面について、さっくり薄いところをご紹介しようかと思います。
Slint の概要
Slintとは
Slint は、Rust で実装された軽量な GUI フレームワークで、独自の宣言的 UI 言語(.slint)を持っています。
特徴としては、
- マイコンからデスクトップ・モバイル・Web までスケールする軽量 GUI ランタイム
- UI 実装のための宣言的言語を提供しており、シンプルで学習しやすい
- Rust との親和性が高く、メモリ安全な UI を構築しやすい
- ランタイムは構成にもよりますが 300KiB 以下の RAM で動作可能
といった点が挙げられます。
対応プラットフォーム(代表例)は以下の通りです。
- Linux
- macOS
- Windows
- iOS / Android
- WebAssembly(ブラウザ)
- 組込み Linux / RTOS(Zephyr など)/ 一部マイコンのベアメタル環境
フレームワーク本体は Rust で実装されていますが、アプリケーションロジックを書く言語としては
- Rust
- C++
- TypeScript / JavaScript(Node.js, Beta)
- Python(Beta)
といった複数の選択肢をサポートしており、好みや既存資産に合わせて選べます。
ライセンスは次の 3 つから選択できます。
-
GPLv3
- オープンソース用途向け(デスクトップ / モバイル / Web / 組込みで利用可能)
-
ロイヤリティフリーライセンス
- デスクトップ / モバイル / Web 向けプロプライエタリアプリを無償で配布可能
- 組込み用途は対象外
-
商用ライセンス
- すべてのプラットフォーム(組込み含む)向けのプロプライエタリ用途
組込み用途で「しっかりサポート付き商用ライセンス」、デスクトップや Web では「GPL / ロイヤリティフリーで手軽に」という使い分けができるのが実務上ありがたいポイントです。
宣言型UI言語
UI の記述は、独自の宣言型言語(.slint)で行います。
HTML のような入れ子構造と、CSS に似たプロパティ記述で GUI を構築していくため、コードを見れば「何がどこに配置されるか」が直感的に分かりやすい構文になっています。
export component MainWindow inherits Window {
width: 640px;
height: 480px;
Text {
text: "hello world";
color: green;
}
}
- レイアウトは
VerticalLayout/HorizontalLayout/GridLayoutなどのコンテナで指定 - プロパティバインディングで値の変化に追従して UI が自動更新
- 状態管理(
states)やアニメーション(animations)も言語レベルでサポート
といった仕組みにより、「UI 側は極力宣言的に」「ロジックはバックエンド言語側で」という役割分担を取りやすくなっています。
Rustとの親和性
Rust は所有権モデルと借用チェックによりメモリ安全性を高めた言語です。
C 系言語とは異なり、所有権・借用・ライフタイム・可変性に独自のルールがあるため学習コストは高めですが、その分、未初期化アクセスや解放済みメモリへのアクセス、データ競合などをコンパイル時点で防いでくれます。
一方で、UI フレームワークはもともと「巨大なオブジェクトツリーの可変共有状態」を大量に扱う世界であり、これは Rust と最も相性が悪いパターンのひとつです。
Slint はここをうまく調停するために、次のような設計になっています。
- UI ツリーは
.slint言語で宣言し、Rust 側からは生成済みコンポーネントへの型安全なアクセサ越しにアクセスする - UI の状態は「プロパティ」として表現し、プロパティバインディングで値の変化を UI 全体へ自動伝播
- Rust 側ロジックとは、コールバックやグローバルシングルトンを通じて疎結合に連携
これにより、
- Rust 側では通常の所有権/借用ルールを守ったまま安全にロジックを書くことができ
- UI 側は宣言的で見通しの良いコードを保ちつつ、双方向のやり取りも行える
という構成を実現しています。
他のGUIフレームワークとの比較
まず、この記事で触れるフレームワークをざっくり一覧にしておきます。
| フレームワーク | 主なターゲット | ロジック言語 | UI記述方式 | 主なライセンス | ローエンド適性 |
|---|---|---|---|---|---|
| Slint | マイコン〜組込み Linux〜デスクトップ / モバイル | Rust / C++ / TypeScript / Python | 宣言型 .slint 言語 |
GPLv3 / ロイヤリティフリー / 商用 | ◎ |
| LVGL | マイコン(8bit/16bit含む) | C / Python / JavaScript / C++ | 命令形コード + GUI ツール | MIT | ◎ |
| Qt / QML | 組込み SoC〜デスクトップ / モバイル | C++ / Python | QML / Qt Designer / コードベース | GPLv3 / LGPLv3 / 商用 | △(Qt for MCUs は別製品) |
| Flutter | モバイル〜デスクトップ / Web | Dart | コードベース宣言型(Dart 内記述) | BSD | △(GPU・メモリ多め前提) |
| GTK | デスクトップ(主に Linux) | C(+各種バインディング) | XML(GtkBuilder) + コードベース | LGPLv2 など | ×(デスクトップ専用寄り) |
| Electron | デスクトップ | JavaScript + HTML + CSS | HTML + CSS(Web 技術) | MIT | ×(Chromium 同梱で重量級) |
- 「ローエンド適性」は、マイコン・低メモリ環境にどこまで素直に持ち込めそうかのざっくり評価です。
- Slint の「ロイヤリティフリー」はデスクトップ / モバイル / Web 向け限定、組込みでプロプライエタリに使う場合は商用ライセンスが必要、という前提で書いています。
Slint
- 言語: Rust / C++ / TypeScript・JavaScript(Node.js, Beta)/ Python(Beta)
-
UI記述:
.slint言語(宣言型言語) - ライセンス: GPLv3 / ロイヤリティフリーライセンス(デスクトップ / モバイル / Web)/ 商用ライセンス(組込み含む)
Slintの良い点(ざっくり)
- 宣言型 UI 言語により UI コードの見通しが良い
- Rust / C++ / Python / TypeScript など好きな言語から利用できる
- ランタイムが小さく、マイコン〜デスクトップまで同じワークフローで扱いやすい
- VS Code 拡張(Language Server)でリアルタイムプレビューや補完が使える
LVGL
- 言語: C / Python / JavaScript / C++(WIP など)
- UI記述: C コードベース、LVGL Designer(別ツール)
- ライセンス: MIT
LVGL はマイコン向けの超軽量な UI フレームワークです。
8bit / 16bit マイコンでも動作し、標準で多数のウィジェットとスタイル・レイアウト機能を備えています。
Zephyr をはじめとした各種 RTOS や ESP-IDF などにも組み込まれており、「とりあえずマイコンで動く GUI」としての実績は非常に豊富です。
LVGLの良い点
- MIT ライセンスで扱いやすく、商用利用もしやすい
- マイコン向けに特化しており、必要リソースが極めて小さい
- 既存プロジェクトやサンプルが豊富で、情報量が多い
Slintの方が優れている点
- 最初から宣言型 UI 言語を提供しており、画面構造がコードだけで把握しやすい
- 公式に VS Code 拡張と Language Server が提供され、開発体験が良い
どちらもマイコンで利用できるという点で比較対象になります。
ライセンスや歴史・実績といった観点では、現時点では LVGL に一日の長があるように感じます。一方で LVGL は命令形スタイルの UI コードになりやすく、画面数が増えると設計・メンテナンスのコストが重くなりがちです。
「UI デザインのしやすさ」「宣言的な記述」「VS Code ベースの開発体験」まで含めて評価すると、個人的には Slint への期待値はかなり大きいです。
Qt / QML
- 言語: C++ / Python(PySide)
- UI記述: Qt Designer(XML)、QML、コードベース
- ライセンス: GPLv3 / LGPLv3 / 商用ライセンス
Qt / QML は歴史が非常に長く、組込みからデスクトップまで幅広く使われているクロスプラットフォームアプリケーションフレームワークです。
近年は GUI だけでなく、ネットワーク、マルチメディア、DB などアプリケーション開発全般をカバーする巨大フレームワークになっており、Qt Creator という専用 IDE も含めて「ある程度以上のハードウェアでは主力」と言ってよい存在です。
Qtの良い点
- LGPL ライセンスでも利用可能(条件を満たせば)
- 実績・コミュニティが非常に豊富
- 表現力が高く、OpenGL / 3D 機能なども充実
- ウィジェット・モジュール・サードパーティ製コンポーネントが大量に存在する
Slintの方が優れている点
- ランタイムが軽量で、ローエンド寄りのハードウェアにも載せやすい
- 組込み向け商用ライセンスが Qt よりも安価なケースが多い(小〜中規模プロジェクトで特に効く)
- Rust を使う場合は cargo だけで完結する構成を取りやすく、ビルド周りがシンプルになりがち
Qt にも「Qt for MCUs」というマイコン向けの軽量版製品がありますが、本家 Qt と比べると別物であり、機能も限定されますし、採用事例もそこまで多くない印象です。
ローエンドの組込では Slint、ハイエンドの SoC を載せたリッチ UI では Qt / QML、といった棲み分けになる場面が多いのではないかと思います。
Flutter
- 言語: Dart
- UI記述: コードベースの宣言型 UI
- ライセンス: BSD 3-Clause
Flutter は Google 製のオープンソース・クロスプラットフォーム UI フレームワークで、1 つのコードベースから iOS / Android / Web / デスクトップ向けアプリをビルドできるのが特徴です。
GPU 前提のリッチレンダリングで、RAM 使用量もそれなりに必要となるため、「いわゆる組込みマイコン」というよりはスマホ〜PC クラスのハードウェア向けと言えます。
Flutterの良い点
- BSD ライセンスで商用利用のハードルが低い
- 日本語情報を含めドキュメント・記事・サンプルが非常に豊富
- マテリアルデザインなどモダンな UI コンポーネントが標準で揃っている
Slintの方が優れている点
- ターゲットハードウェアに対する要求(CPU / RAM)が小さい
- Dart ではなく Rust / C++ / Python / TypeScript など、既存資産と合わせやすい言語を選べる
Flutter は UI 記述自体は宣言型ですが、Dart コードに埋め込む形で書くため、画面規模が大きくなると「UI とロジックの境界」がやや見えづらくなることがあります。
個人的には Flutter をほとんど触れていないので、ここは聞きかじりの範囲も多く、ご容赦ください……という前提付きですが、ハイスペック環境でリッチ UI を作るなら Flutter / Qt、ローエンド寄りで Rust との組み合わせを考えるなら Slint、という棲み分けがしっくり来そうです。
GTK
- 言語: C
- UI記述: XML(GtkBuilder) + コードベース
- ライセンス: LGPLv2 など
GTK は GNOME デスクトップ環境の下支えをしている GUI フレームワークです。
現在は GPU 前提の設計になっており、基本的にはデスクトップ用途向けと考えてよいでしょう。
GTKの良い点
- LGPL ライセンスで利用でき、OSS / 商用どちらにも使いやすい
- 長い歴史と実績があり、Linux デスクトップ系アプリケーションとの相性が良い
Slintの方が優れている点
- ランタイムが軽量で、マイコン・組込み機器でのパフォーマンスに優れる
- GObject ベースのオブジェクトシステムに乗らなくてよい(Rust / C++ から自然な形で扱える)
GTK は言語バインディングが豊富で柔軟ですが、C ベース + GObject という前提があるため、「いまから新規に GTK で GUI を始める」ケースは以前と比べると減っている印象です。
Linux デスクトップアプリを作るなら依然として強力ですが、組込みのマイコンや軽量 SoC に持ち込むなら Slint のほうが現実的です。
Electron
- 言語: JavaScript + HTML + CSS
- UI記述: HTML + CSS(フロントエンドフレームワーク自由)
- ライセンス: MIT
Electron は Web 技術を用いてクロスプラットフォームなデスクトップアプリを開発できるフレームワークです。
Chromium(ブラウザエンジン) + Node.js をバイナリに同梱して動作します。
Visual Studio Code / Slack / Discord など、有名どころのデスクトップアプリが多数 Electron ベースで動いているので、「デスクトップ向け実績」という面では非常に強い存在です。
Electronの良い点
- MIT ライセンスで扱いやすい
- HTML / CSS / JavaScript の知識がそのまま生きるため、学習コストが低い
- npm エコシステムを活用でき、フロントエンドのライブラリをほぼそのまま利用可能
Slintの方が優れている点
- ランタイムが軽量で、マイコン・ローエンド組込み機器でも現実的なパフォーマンスを出しやすい
- ネイティブツールキットとして動作するため、GPU / ソフトウェアレンダリングなどのバックエンドを直接利用できる
- C++ / Rust / Python などと同じプロセス内で完結するネイティブアーキテクチャ
Slint も Node.js 連携(slint-node, Beta)を提供しているので、「Node.js × Slint」という構成で書くことも可能です。
とはいえ、現時点でデスクトップ向けの実績・採用事例という点では Electron に軍配が上がるでしょう。他方で、Electron は Chromium ごと同梱するため RAM やストレージの要求が大きく、ローエンド環境には向いていません。
まとめ
というわけで、本日は簡単に最近も耳にするGUIフレームワークとSlintをざっくり比較してみました。
本当は、同じGUIをそれぞれで作ってメモリ使用量とかパフォーマンス比較とかも知ればよいのでしょうけど、そもそも得意分野が違いますし、単純比較できる部分でもないのでなかなか難しいですよね。
Slintも2.0に向けてデスクトップアプリケーション向けの機能も充実させていくという公式発表も出ていますが、今の所、他のフレームワークと比較してみると、立ち位置としてはローエンド組込向けで、特にタッチパネルを持つUI向けのフレームワークになっています。
海外ではだいぶ注目度も上がってきており、着々と開発が進められているところです。日本ではまだ知名度が低いですが、日本でも流行るといいなぁと思いながら、今年もちらほらカレンダー記事を書いていきたいなと思います。