「Electron 製アプリ重すぎ問題」を解消する、10MB で動く Node.js 製ネイティブアプリを作ってみた
Electron のようにブラウザエンジンを内包している「ネイティブアプリ」、ちょくちょくありますよね。Slack、ChatGPT などの Windows 版はそういう仕組みだったりします。
これらは Electron フレームワークの中に Chrome ブラウザ的なモノが内包されており、動作の実態は「そのアプリ専用の Chrome ブラウザ」みたいな状態ですので、Chrome で常に1タブ開きっぱなし、みたいなのに近いメモリ容量を食います。
さらに、ネイティブアプリとして動作する exe ファイルにブラウザエンジンや Node.js ランタイムを内包しているので、バンドルサイズも 100~200MB くらいになることが大半です。ファイルサイズも食うワケです。
そこで思いました。「Edge や Chrome などのブラウザはどのマシンにも入ってる。Node.js ランタイムも開発者だったら入れてるだろう。じゃあ、タスクトレイアイコンとして常駐する部分だけあれば、後は Node.js スクリプトだけで動くのでは?」と。
色々調べて、ChatGPT と Claude に相談して、PoC プログラムを実装してみました。名付けて「Light Native App」です。
詳細
今回は「Windows ネイティブアプリ」としての実装のみです。Mac や Linux には対応していません。
Windows 環境に Node.js ランタイムがインストールされている必要があります。nvm-windows あたりでインストールしておいてください。
Node.js プログラムが必要な理由は、ローカルファイルの読み書きとか、ブラウザ上だけでは実行しづらい処理が主かな、と思ったので、サンプルプログラムは「テキストエディタ」としました。
Hono でバックエンド API を立て、http://localhost:11647 が起動します。コレを任意のブラウザで開くことで、React フロントエンドが表示され、アプリケーションとして利用できます。
コレだけだと、起動のたびに $ node ./server.js みたいなモノを叩いてコンソールを立ち上げっぱなしにする必要があると思いましたので、プロセスとしてはタスクトレイに常駐することにしました。
色々調べたのですが、タスクトレイ常駐を実現するにはどうしても Node.js 単体での実装は難しく、Go 言語でランチャー部分を実装して exe 化しました。この辺の実装は Claude に任せましたが、コード量が少ないので自分でも読み書きできる程度になりました。
タスクトレイアイコンからは、マシンにインストールされているブラウザ一覧を特定して、「Chrome で開く」とか「Edge で開く」みたいなメニューを用意してあげることで、いつでもブラウザタブを閉じて大丈夫、再度開きやすくしました。
exe ファイル込みで 10MB で「ネイティブアプリ」を実現
そんなワケで、ランチャーとタスクトレイ常駐部分に Go 言語を使いましたが、Hono バックエンド・React フロントエンド部分は何のフレームワークを使っても実は関係なく、任意のフレームワークに差し替えて実装ができます。
そしてブラウザエンジンと Node.js ランタイムを内包しなくなったので、配布資材としては 10MB で全てが完結するサイズになりました。以下がその詳細です。
$ tree dist/ --du -h
[9.8M] dist/ … 全体で 10MB に収まりました
├ [251K] assets/
│ ├ [ 85K] index.js … Hono サーバ・Node.js プログラムのエントリポイント
│ └ [162K] public/ … React フロントエンド
│ ├ [ 407] index.html
│ └ [141K] index.js
├ [9.5M] light-native-app.exe … この exe を叩いて起動する
└ [ 147] light-native-app.json … デバッグ用などの設定を行うための設定ファイル (なくても動く)
もちろん Node.js プログラム部分を開発していけば容量は増えるかと思いますが、Go 言語で書いたランチャー部分は実装を大きく変更することはないでしょうし、.exe のエントリポイントは 9.5MB でほぼ固定です。
Windows ホストに Node.js ランタイムを必要とするため、完全に一般的なユーザ向けのアプリとしては向かないかもしれませんし、今回「インストーラ」としてまとめる部分の実装がありませんので、インストーラ部分で「Node.js が見つからないのでインストールを促す」といった機能を提供すれば良いようにも思います。
今回も PoC の実装には Claude にお世話になりました。AI のおかげで簡単に概念実証が組めて最高裁判所な世の中になりましたね。