---
title: "Elixir Desktopとは？LiveViewアプリのネイティブ化と導入手順"
url: "https://www.issoh.co.jp/tech/details/3946/"
published: 2024-10-24
updated: 2026-10-20
categories: ["プラットフォーム"]
publisher: "株式会社一創"
---

# Elixir Desktopとは？LiveViewアプリのネイティブ化と導入手順

Elixir Desktopは、Phoenix LiveViewで書いたアプリをそのままネイティブウィンドウの中で動かすためのHexライブラリです。名前から「Elixir製のデスクトップ環境」や「GUIツールキット」を想像すると設計を読み違えます。実体は、アプリ内でPhoenixサーバーを起動し、その画面をOS標準のWebViewで表示する薄い層です。この記事では製品の正体と動作の仕組み、ElectronやTauriとの選び分け、必要環境と最小構成の改修、Hex公開版と開発ブランチの乖離までを、公式リポジトリとhex.pmの一次情報で整理します。

## まとめ

Elixir Desktopはデスクトップ環境ではなく、Phoenix LiveViewアプリをWebViewで包んでWindows・macOS・Linux・iOS・Androidに配るためのMITライセンスのライブラリです。Hexでのパッケージ名は`desktop`で、GitHubのstarは1,796、リポジトリは2026年8月2日にもコミットが入っています（2026年8月5日時点・GitHub API実測）。

採用判断で最も重要なのは、**Hexで公開されている最新版が1.5.3（2024年3月27日公開）のまま止まっている一方、mainブランチは1.6として開発が続いている**という乖離です。公式ガイド自身が依存指定を`{:desktop, github: "elixir-desktop/desktop"}`と書いており、Hex版を前提にした解説記事とは前提が食い違います。導入に必要なのはErlang OTP 24以上（wxWidgets 3.1.15以上を含むもの）とElixir 1.11.4以上、ただし推奨されるmain経路では実質1.15以上、そして既存Phoenixアプリ側で触るのはmix.exsの依存追加を除けば3ファイルだけです。

## Elixir Desktopの正体とデスクトップ環境との違い

### KDEやGNOMEと同列に語れない理由

Elixir Desktopを「Elixirで書かれたデスクトップ環境」と説明する解説を見かけますが、これは誤りです。KDEやGNOMEはウィンドウマネージャやファイルマネージャ、パネルを含むOSのシェルそのものであり、ユーザーがログイン時に選ぶ実行環境です。対してElixir Desktopは、既存のPhoenixアプリケーションのmix.exsに1行足して使うライブラリで、単体では何も表示しません。比較すべき相手はKDEやGNOMEではなく、Web技術をネイティブアプリに包むElectronやTauriです。

混同が起きるのは名前だけが理由ではありません。GitHubの組織名が`elixir-desktop`である一方、Hexで公開されているパッケージ名は`desktop`という一般名詞で、hex.pmの説明文も「Building native-like Elixir apps for Windows, MacOS, Linux, iOS and Android using Phoenix LiveView!」とだけ書かれています。パッケージ名から機能を推測しにくいライブラリなので、mix.exsで見かけた際は組織名まで確認してください。

もうひとつ、自己説明が2種類あることも押さえておくと読み違いを避けられます。hex.pm側が「native-like」と書いているのに対し、GitHubリポジトリ側の説明文は「Building Local-First apps for Windows, MacOS, Linux, iOS and Android using Phoenix LiveView & Elixir!」に更新されています。オフラインで完結する業務ツールという用途を前面に出す方向へ、プロジェクトの自己定義が寄っている状況です。

### 5プラットフォーム対応とMITライセンスの範囲

公式READMEが対応を明言しているのはWindows、macOS、Linux、iOS、Androidの5つです。ライセンスはMITで、著作権表記は2021年のDominic Letz氏名義です。リポジトリは2021年3月1日に作成され、同日時点でfork 63・オープンissue 3件、アーカイブはされていません。Hexの累計ダウンロードは16,163、直近90日は1,750、直近7日は134です。大規模に使われている基盤というより、Elixirコミュニティ内で継続的に触られている規模と読むのが実態に近い数字です。

## 動作の仕組みはローカルPhoenixサーバーとWebViewの組み合わせ

### アプリの中で完結する3層構造

Elixir Desktopのアプリは、通常のPhoenixアプリと同じHTTPサーバーを自分自身のプロセス内で起動します。ただしバインド先は`127.0.0.1`、ポートは`0`を指定してOSに空きポートを選ばせます。その上でネイティブウィンドウを開き、中に埋め込んだWebViewからローカルサーバーのURLを読み込む、という3層構造です。ブラウザは立ち上がらず、ユーザーからはひとつのアプリケーションに見えます。

Windows・macOS・Linuxでは、ネイティブウィンドウの生成にErlang/OTPに同梱される`:wx`（wxWidgetsのErlangバインディング）を使います。iOSとAndroidでは経路が変わり、ネイティブホストアプリ側のWebViewへブリッジする実装に差し替わります。ElectronのようにChromiumを同梱するのではなく、OSが持つWebViewを借りる設計なので、配布物にブラウザエンジンを丸ごと抱える必要がありません。この点はTauriの考え方に近く、詳しい対比は[Tauriとは？Electronとの違い・将来性・始め方まで徹底解説【2026年版】](/tech/details/4114/)で扱っている構成の違いがそのまま参考になります。

### ローカルサーバーを守るDesktop.Auth

ローカルにHTTPサーバーが立つと聞くと、同じPC上の別プロセスから叩かれないかが気になります。Elixir Desktopはこれを`Desktop.Auth`というPlugで塞いでいます。実装（lib/desktop/auth.ex）を読むと、`:crypto.strong_rand_bytes(32)`で生成した32バイトの鍵を保持し、Base32エンコードしたトークンをクエリパラメータ`k`に持つリクエストだけを通す仕組みです。照合には`Plug.Crypto.secure_compare/2`が使われます。鍵はアプリの起動ごとに作り直されるため、起動中は同じ値が使われ、再起動すれば別の値になります。

ただしこの照合が働くのはデスクトップの3プラットフォームだけです。条件は`if OS.mobile?() or Plug.Crypto.secure_compare(...)`と書かれており、`Desktop.OS.mobile?/0`が真になるiOSとAndroidでは、ホストアプリ自体が窓口になるため照合を飛ばします。

つまりデスクトップではポートを推測されてもトークンがなければ画面は開けません。導入時にこのPlugを入れ忘れると、ローカルに認証なしのWebアプリを晒すことになります。後述する書き換えのうち、省略してはいけないのがこの1行です。

## ElectronやTauriとの選定基準

Web技術でデスクトップアプリを作る選択肢は複数ありますが、Elixir Desktopが選ばれる条件ははっきりしています。**すでにPhoenix LiveViewでアプリを書いていること**です。LiveViewはUIの1操作ごとにサーバーとWebSocketで往復しますが、デスクトップアプリではその相手が同じマシンのループバックになるため、Web配信時に効いてくる往復遅延の影響を受けません。

| 観点       | Elixir Desktop  | Electron        | Tauri            |
| -------- | --------------- | --------------- | ---------------- |
| UIの実行主体  | サーバー側（LiveView） | クライアント側JS       | クライアント側JS        |
| 描画エンジン   | OS標準WebView     | Chromium同梱      | OS標準WebView      |
| バックエンド言語 | Elixir / Erlang | Node.js         | Rust             |
| ネイティブ層   | :wx / wxWidgets | Chromium + Node | Rust + WRY / TAO |
| ライセンス    | MIT             | MIT             | MIT / Apache-2.0 |

逆に、JavaScriptでフロントを組む前提のチームがElixir Desktopを選ぶ理由はほとんどありません。その場合は[Electronとは？Web技術でデスクトップアプリを作る入門解説【2026年最新】](/tech/details/3322/)で扱う成熟したエコシステムのほうが、周辺ツールもドキュメントも揃っています。Elixir Desktopの価値は「既存のLiveViewコードとBEAMの並行処理をそのまま持ち込めること」に集約されるため、そこに当てはまらない案件では選定理由が立ちません。

## 導入手順は環境要件の確認と3ファイルの書き換え

### 前提となるErlang・Elixir・wxWidgetsのバージョン

公式のGetting Startedガイドが明示している要件は、Erlang OTP 24以上（wxWidgets 3.1.15以上を伴うもの）とElixir 1.11.4以上です。公開版1.5.3のmix.exsも`elixir: "~> 1.11"`を宣言しています。注意したいのはwxWidgets側で、単にErlangが入っているだけでは足りず、`:wx`がWebViewを扱える構成でビルドされている必要があります。Debian系ではガイドが挙げるaptパッケージに`libwxgtk-webview3.0-gtk3-dev`が含まれており、この`webview`付きパッケージを入れ忘れるとウィンドウは開いても中身が描画されません。

ただしこの1.11.4という下限が効くのは、Hex版1.5.3（`phoenix_live_view "> 0.15.0"`）を使う経路に限られます。後述するとおり公式が案内するのはmainを直接参照する経路で、mainは`phoenix_live_view "> 1.0.0"`を要求します。LiveView側の実バージョンはhex.pmのメタデータで1.0.0が`~> 1.14.1 or ~> 1.15`、現行の1.2.8が`~> 1.15`とElixir要件を宣言しているため、**main経路の実質的な下限はElixir 1.15以上**です。1.11.4のまま依存解決をかけると失敗します。

実際、リポジトリのmainに置かれた`.tool-versions`はerlangが`26.2.5.5 system`（システム導入版へのフォールバック付き）、elixirが`1.19.1-otp-26`を指しています。これが開発者側の検証している組み合わせなので、最低要件のOTP 24ではなくこちらに寄せるほうが踏み外しは減ります。miseやasdfを使っているなら、mainには`mix desktop.check_toolchain`という照合用タスクも用意されています。

版差が効くのはランタイム要件だけではありません。Elixir 1.20では、ビットパターン内の`size(...)`へマッチ外の変数を渡す書き方がハード非推奨になり、ピン演算子が要求されるようになりました。バイナリを扱うコードを含むアプリを新しいElixirへ上げる場合は、[バイナリのパターンマッチで出る新しい警告](/tech/details/4363/)もあわせて確認してください。

### 依存指定がgithub:になる理由

公式ガイドが案内する依存の書き方は、Hexのバージョン指定ではなくGitHubの直接参照です。

```
def deps do
  [
    # ...
    {:desktop, github: "elixir-desktop/desktop"}
  ]
end
```

Hexに公開されている最新版が1.5.3で2024年3月27日から更新されていないのに対し、mainブランチには2026年8月2日のコミットまで入っています。この2年4か月ぶんの修正を取り込むには`github:`指定を使うしかない、というのが公式がこう書いている理由です。バージョンを固定したい場合は`ref:`にコミットSHAを指定します。安定を優先してHex版を使う判断もありますが、その場合はmainにしかない機能の解説記事をそのまま真似ても動きません。

### Endpoint・Application・configの書き換え内容

既存のPhoenix LiveViewアプリをデスクトップアプリにするために触るのは、mix.exsの依存追加を除けば3ファイルだけです。まずEndpointモジュールを`Desktop.Endpoint`に差し替え、前述の`Desktop.Auth`をRouterの手前に挟みます。

```
defmodule DemoWeb.Endpoint do
  use Desktop.Endpoint, otp_app: :demo

  # ...

  plug Desktop.Auth
  plug DemoWeb.Router
end
```

なお公式ガイドはこの最終行を`plug YourAppWeb.Router`と書いていますが、同じ例で使っているモジュール名は`DemoWeb`です。そのまま写すと未定義モジュールで落ちるため、上記のように自分のアプリ名へ揃えてください。

次にアプリケーションのスーパーバイザーツリーへ`Desktop.Window`を追加します。`url:`にはEndpointのURLを返す関数を渡します。ポートが実行時に決まるため、値ではなく関数を渡すのが要点です。

```
def start(_type, _args) do
  children = [
    # ...
    DemoWeb.Endpoint,
    {Desktop.Window,
     [
       app: :demo,
       id: DemoWindow,
       url: &DemoWeb.Endpoint.url/0
     ]}
  ]

  Supervisor.start_link(children, strategy: :one_for_one, name: Demo.Supervisor)
end
```

最後に`config/dev.exs`（リリース時は`config/runtime.exs`）で、ループバックへのバインドと自動ポート割り当て、そしてサーバーの自動起動を指定します。

```
config :demo, DemoWeb.Endpoint,
  http: [ip: {127, 0, 0, 1}, port: 0],
  server: true
```

あとは`mix run --no-halt`で起動すればウィンドウが開きます。多言語対応が必要なら、children を組み立てる前に`Desktop.identify_default_locale(DemoWeb.Gettext)`を呼ぶとOSの言語設定を拾えます。ゼロから試すなら、star 270の`desktop-example-app`リポジトリが動く出発点として公開されています。

ビルド環境の準備はプラットフォームごとに異なります。WindowsではWSLではなくmsys2を使います。公式ガイドは、WSLが入っていないWindows機でも動くネイティブアプリを作るためだと理由を明記しています。インストーラまで作る場合はNSISの導入も必要です。iOSとAndroid向けは、organizationが公開する`android-example-app`と`ios-example-app`が出発点になります。

## Hex版1.5.3とmainの差分は採用前に必ず確認

### 1.6（未リリース）で入ったバックエンド切り替え

ここが日本語の解説記事でほとんど触れられていない、採用判断を左右する差分です。mainのCHANGELOG.mdは冒頭が「Changes in 1.6 (unreleased)」で始まり、内部構造の大きな作り替えが列挙されています。中心は`Desktop.Platform`という抽象層の導入で、ウィンドウ・コンテンツ・通知・メディア・システムの各操作が3つのバックエンドに振り分けられるようになりました。

| バックエンド                  | 用途                      | ウィンドウ | コンテンツ       |
| ----------------------- | ----------------------- | ----- | ----------- |
| Desktop.Backend.Wx      | Windows / macOS / Linux | あり    | WebView     |
| Desktop.Backend.Json    | iOS / Android（ネイティブホスト） | あり    | ホスト側WebView |
| Desktop.Backend.Browser | CI・GUIなしのサーバー           | なし    | OS既定ブラウザ    |

既定は`:auto`で、モバイル指定があればJson、`NO_WX`が設定されているか`:wx`が使えなければBrowser、それ以外はWxが選ばれます。設定で明示的に固定することもできます。

```
config :desktop, :backend, :auto     # 既定（自動選択）
config :desktop, :backend, :wx       # wxWidgetsのネイティブウィンドウ
config :desktop, :backend, :json     # モバイルのネイティブホストへブリッジ
config :desktop, :backend, :browser  # ウィンドウを作らずOS既定ブラウザで開く
```

この3つに加えて、`Desktop.Platform.*`のビヘイビアを実装した自作モジュールを`config :desktop, :backend, MyApp.DesktopBackend`の形で差し込むこともできます。独自メニューアダプタを持つ実装では`config :desktop, :menu_adapter`もあわせて指定します。

実務で効くのはBrowserバックエンドです。`NO_WX=1`を渡すだけでwxWidgetsのないCI環境でもアプリを起動できるため、これまでGUI必須で回らなかった自動テストが動かせます。1.6ではあわせてテストが`mix test.fast`・`xvfb-run mix test.wx`・`mix test.guard`の3つに分離され、wxに依存しないテストだけを先に流せるようになりました。

### 公開版とmainの選択基準

公開版1.5.3のtarballを展開してlib配下を確認したところ、`backend/`も`platform/`も`mix/tasks/`も存在しません。つまり上記のバックエンド切り替え、`NO_WX`による起動、`mix desktop.install`や`mix desktop.check_toolchain`はHex版では一切使えません。依存関係の宣言にも差があり、公開版が`phoenix_live_view "> 0.15.0"`と緩く広い範囲を許すのに対し、mainは`phoenix "> 1.7.10"`・`phoenix_live_view "> 1.0.0"`と新しい世代を前提にしています。

差は機能の有無だけではありません。mainでは2026年7月22日に、`Window.prepare_url/1`とAuthプラグが同時に初回アクセスすると別々の鍵が発行され、WebViewが空の「Unauthorized」画面のまま止まる競合が修正されています。ソース中のコメントにその症状が明記され、ETSの`insert_new`で鍵の勝者を1つに決める実装へ変わりました。Hex版1.5.3はこの修正を含みません。

判断としては、新規に始めるなら公式ガイドどおり`github:`指定でmainを使うほうが筋が通ります。Hex版1.5.3を選ぶのは、LiveView 0.x世代の既存アプリを動かし続ける場合に限られます。バージョン番号だけを見て「最新は1.5.3」と判断すると、2年4か月ぶんの修正と1.6の新機能を丸ごと取り逃します。

## 採用を見送るべきケース

Elixir Desktopが向かない条件も明確です。第一に、**Windows・macOS・Linux向けのインストーラを自動生成したい案件**には現時点で勧められません。READMEのRoadmapは8項目のうち達成済みが1〜3（3プラットフォームでの実行、iOS/Androidでの実行、iOS/Android向けパッケージング）までで、4以降のデスクトップ向けインストーラ生成、コード署名の統合、自動更新フローは未達のまま残っています。配布スクリプトを集めた`deployment`リポジトリも、説明文自体が「Still raw repo with deployment scripts」と断っている状態です。配布まで含めた仕組みが必要なら、その部分は自前で用意する前提で見積もってください。

ここは公式ドキュメントの記述と食い違うので補足します。`guides/faq.md`には`mix desktop.installer`を実行すればWindows・macOS・Linux向けのインストーラ（`.exe`、`.dmg`、`.AppImage`、`.deb`、`.rpm`）を生成できると書かれています。しかし2026年8月5日時点のmainブランチを走査すると、`lib/mix/tasks/`に存在するのは`desktop.install`と`desktop.check_toolchain`の2本だけで、`desktop.installer`というタスクは実在しません。Roadmapが未達と言っているほうが実態です。ガイドの記述を鵜呑みにして配布計画を立てないでください。

第二に、LiveViewを使っていないチームです。ElixirでAPIサーバーだけを書いていて画面はReactという構成なら、Elixir Desktopに載せ替える利点はほぼありません。第三に、wxWidgets付きのErlangランタイムを自前でビルドして配布物に同梱できない場合です。利用者にErlangを入れさせるのではなく作り手がランタイムを同梱するのが前提ですが、Roadmapの6番（事前ビルド済みErlangバイナリの利用）が未達のため、ランタイムの調達は現状では各プロジェクトの持ち出しになります。

逆に、社内向けの業務ツールをLiveViewで作っていて、それをオフラインでも動く単体アプリとして配りたい、というケースは最も相性の良い使いどころです。サーバーもUIも同じコードのまま、配布形態だけを変えられます。

## よくある質問

### Elixir DesktopはKDEやGNOMEのようなデスクトップ環境ですか？

いいえ。Hexで`desktop`という名前で公開されているライブラリで、既存のPhoenixアプリのmix.exsに依存として追加して使います。単体では動作しません。なおElixirでGUIを作ること自体が目的なら、Erlang/OTP同梱の`:wx`を直接叩いて従来型のウィジェットアプリを組む道もあります。Elixir DesktopはあくまでLiveViewの画面をそのまま配りたい場合の選択肢です。

### Hexの最新版はいつ更新されましたか？

公開されている最新版は1.5.3で、公開日は2024年3月27日です。一方GitHubのmainブランチには2年4か月後の2026年8月2日のコミットが入っており、開発自体は続いています。公式ガイドもHexのバージョン指定ではなく`{:desktop, github: "elixir-desktop/desktop"}`を案内しているため、再現性を保ちたい場合は`ref:`にコミットSHAを添えて固定するのが実務的です。

### Elixir Desktopでスマートフォンアプリも作れますか？

作れます。READMEのRoadmapでiOSとAndroidでの実行およびパッケージングは達成済みとされており、star 113のandroid-example-appとstar 79のios-example-appという動作するサンプルが公開されています。Erlang/Elixirランタイム自体もorganizationの`runtimes`リポジトリで配布されています。

### Windows向けのインストーラは作れますか？

公式が用意した自動生成の仕組みは同日時点でまだ完成していません。READMEのRoadmapでは、Windows・macOS・Linux向けインストーラのパッケージングとコード署名の統合が未達項目として残っています。`guides/faq.md`には`mix desktop.installer`で生成できるという記述がありますが、そのMixタスクはmainブランチに実在しないため当てにできません。実行ファイルとして動かすところまでは可能ですが、インストーラ作成と署名は自前で組む前提で計画してください。

### ローカルにWebサーバーが立つのはセキュリティ上問題ありませんか？

`Desktop.Auth`というPlugが同梱されており、これを挟むことで対策されています。バインド先が`127.0.0.1`に限定されたうえ、起動ごとに作られる鍵をBase32化したトークンをクエリパラメータ`k`で受け取り、`Plug.Crypto.secure_compare/2`で照合します。ただしiOSとAndroidではホストアプリが窓口になるためこの照合は行われません。またデスクトップでも導入時にPlugを書き忘れると保護が効かないため、Endpointの書き換え時に必ず入れてください。

## 関連記事

- [Tauriとは？Electronとの違い・将来性・始め方まで徹底解説【2026年版】](/tech/details/4114/)
- [Electronとは？Web技術でデスクトップアプリを作る入門解説【2026年最新】](/tech/details/3322/)
- [Gleamとは？Erlang VM上で動く型安全な関数型プログラミング言語](/tech/details/8943/)
- [Elixirのバイナリとパターンマッチ｜ビット文字列との違いと1.20の変更点](/tech/details/4363/)

---

出典: [Elixir Desktopとは？LiveViewアプリのネイティブ化と導入手順](<https://www.issoh.co.jp/tech/details/3946/>)（株式会社一創）
