huggingface/chat-ui を採用する前に読む: OpenAI 互換 API 専用に舵を切った SvelteKit チャット基盤
The open source codebase powering HuggingChat
ひと目でわかる
- これは何?
- HuggingChat を動かしている SvelteKit 製チャット UI の現行ブランチは、プロバイダ固有の連携を削ぎ落として OpenAI 互換 API と MongoDB に絞り込んでいる。その設計と代償を、リポジトリの記述だけを根拠に整理する。
- 誰に向いている?
- 採用を検討すべきなのは、OpenAI 互換のエンドポイントをすでに持っていて、MongoDB を運用に載せられるチームである。llama.cpp server や Ollama、OpenRouter を `OPENAI_BASE_URL` で指せるなら、チャット UI を自作するより速い。
- 商用利用できる?
- できます。Apache-2.0 は寛容なライセンスで、著作権表示とライセンス表示を残せば、使用・改変・販売が可能です。
- 今もメンテナンスされている?
- されています。直近 1 日以内に新しいコミットがあります。
- 何の言語で書かれている?
- 主に TypeScript です(GitHub の言語統計による)。
回答はプロジェクトの GitHub データ(最終同期:2026年9月15日)と当サイトの分析に基づくもので、法的助言ではありません。
オープンソース詳細解説
HuggingChat の本体を自前で立てるという選択
このリポジトリが解く問題は、LLM 用のチャット画面をゼロから作らずに済ませることである。README によれば SvelteKit アプリであり、hf.co/chat の HuggingChat を動かしている本体そのものだ。つまり公開サービスとして動いているコードがそのまま配布されている。
想定読者は、モデルはすでに動かせるが UI と会話履歴の管理を持っていないチームだ。会話ログ、ユーザー、設定、ファイル、統計はすべて MongoDB に置かれると README は説明しており、ステートレスなフロントエンドではなく、永続化を前提とした構成になっている。個人がローカルで試す用途も想定されていて、`MONGODB_URL` を設定しない場合は `./db` に永続化する組み込み MongoDB にフォールバックする。
現行ブランチは OpenAI 互換 API だけを話す
このブランチの性格を決めているのは、プロバイダ固有の連携を削ったという判断である。README の注記は、`OPENAI_BASE_URL` と `/models` エンドポイント経由の OpenAI 互換 API のみをサポートし、レガシーな `MODELS` 環境変数、GGUF の検出、埋め込み、Web 検索ヘルパーなどは削除されたと明記している。
代わりに得られるのは接続先の自由度だ。OpenAI プロトコルを話すサービスなら既定で動くとされ、README の表には Hugging Face Inference Providers router、llama.cpp server、Ollama、OpenRouter、Poe の例が並ぶ。llama.cpp の場合は `OPENAI_API_KEY` に任意の文字列を入れてよく、サーバー側が無視するという注記まで付いている。ここは実務上ありがたい。ローカル推論を試すのに API キーの発行が要らない。
一方で、この整理は後退でもある。GGUF の自動検出が消えたということは、モデルファイルを置けば一覧に出る、という体験はもう期待できない。モデルの一覧は `${OPENAI_BASE_URL}/models` から取得され、メタデータを上書きしたい場合だけ `MODELS` 環境変数に JSON5 を書く、という役割分担に変わっている。
環境変数3つで立ち上がるまで
README の Quickstart は短い。`.env.local` を作り、`OPENAI_BASE_URL` と `OPENAI_API_KEY` を書く。Hugging Face の router を使うなら前者が `https://router.huggingface.co/v1`、後者が `hf_` で始まるトークンになる。`HF_TOKEN` はレガシーな別名として残っていると README は述べている。
そのうえで `git clone`、`npm install`、`npm run dev -- --open` を実行する。開発サーバーは既定で `http://localhost:5173` を待ち受ける。本番ビルドは `npm run build` と `npm run preview` である。
MongoDB はローカル開発なら省略できる。`MONGODB_URL` が未設定なら `./db` に永続化する組み込みの MongoDB が使われる。外部に置く場合の選択肢は2つ示されている。MongoDB Atlas の無料クラスタを作り、接続文字列を `MONGODB_URL` に入れ、`MONGODB_DB_NAME` は既定の `chat-ui` のままか環境ごとに変える。あるいは `docker run -d -p 27017:27017 --name mongo-chatui mongo:latest` でコンテナを立て、`MONGODB_URL=mongodb://localhost:27017` を指定する。対応するのは MongoDB 6 と 7 だと README は書いている。
コンテナで丸ごと動かしたい場合のために `chat-ui-db` イメージも用意されている。MongoDB を内包したイメージで、`ghcr.io/huggingface/chat-ui-db:latest` を `-p 3000:3000` と `-v chat-ui-data:/data`、そして `-e` で環境変数を渡して起動する。`.env.local` に書ける変数は `-e` フラグとして渡せる。
LLM Router はローカル heuristic でルートを選ぶ
現行ブランチで最も説明を要するのがこの機能だ。Chat UI はサーバー側でスマートルーティングを行えるが、別のルーターサービスや選択用モデルを呼び出すのではなく、ローカルの heuristic で判断すると README は述べている。UI 上には「Omni」という仮想モデルの別名が現れ、これを選ぶとメッセージごとにルートが決まる。画像入力は `multimodal`、MCP ツールが有効なリクエストは `agentic`、それ以外は `default` に振り分けられる。
設定は `LLM_ROUTER_ROUTES_PATH` でルート方針の JSON を渡す。ここが注意点で、このブランチにはサンプルファイルが同梱されていない。自分で JSON 配列を用意し、例えば `config/routes.chat.json` としてリポジトリにコミットする必要がある。各エントリには `name`、`description`、`primary_model`、そして任意で `fallback_models` が要る。ルーターが認識するルート名は `default`、`multimodal`、`agentic` の3つである。
既定のルート名は `LLM_ROUTER_DEFAULT_ROUTE` で変えられる。選択したルートのモデルがすべて失敗した場合、呼び出しは `LLM_ROUTER_FALLBACK_MODEL` に落ちる。Omni の別名自体は `PUBLIC_LLM_ROUTER_ALIAS_ID`(既定 `omni`)、`PUBLIC_LLM_ROUTER_DISPLAY_NAME`(既定 `Omni`)、任意で `PUBLIC_LLM_ROUTER_LOGO_URL` で調整する。
動作の流れは README に沿って言えばこうだ。Omni を選ぶと、リクエストの信号からルートをローカルで選び、`RouterMetadata` を即座に出力して実際に使われたルートとモデルを UI に表示させ、選ばれたモデルから `OPENAI_BASE_URL` 経由でストリームする。エラー時はルートのフォールバックを試みる。設定ファイルを自前で書く手間と引き換えに、ルーティング用の追加サービスを立てずに済む設計だと言える。
見た目とデータ共有は PUBLIC_ 変数で決まる
ブランディングまわりは環境変数で完結する。`PUBLIC_APP_NAME` はアプリ全体のタイトルになり、既定は `ChatUI`。`PUBLIC_APP_ASSETS` はロゴとファビコンの探索先で、`static/$PUBLIC_APP_ASSETS` を見に行く。現在の選択肢は `chatui` と `huggingchat` の2つだと README は書いている。つまり任意の名前を入れて任意のディレクトリを指せるわけではなく、用意された2種類から選ぶ形だ。ここは地味な制約である。
`PUBLIC_APP_DATA_SHARING` を 1 にすると、ユーザー設定にデータ共有のトグルが現れ、モデル作成者へのオプトインを選べるようになる。公開サービスとして運用するなら、この設定を入れるかどうかは方針判断になる。
なお `PUBLIC_` 接頭辞が付く変数はクライアントに露出する。アプリ名やアセットの場所はともかく、これらに秘匿情報を入れてはいけないという一般則は、この構成でも変わらない。
向かない場面と、legacy ブランチという逃げ道
最大の制約は、プロバイダ固有の連携が消えたことである。埋め込みや Web 検索ヘルパーを前提にした機能を組み込んでいた場合、このブランチでは動かない。README は削除されたものとしてそれらを列挙している。GGUF の検出も同じ扱いだ。
もうひとつは MongoDB が必須である点だ。開発時は組み込みにフォールバックするが、会話履歴、ユーザー、設定、ファイル、統計のすべてが MongoDB に載るということは、本番では MongoDB の運用、バックアップ、バージョン管理がそのままサービス運用になる。MongoDB 6 か 7 という対応範囲も、既存のクラスタが古い場合には制約になる。
LLM Router にも落とし穴がある。サンプル設定が同梱されていない以上、ルート方針 JSON は自分で設計しなければならない。ルート名が `default`、`multimodal`、`agentic` の3つに固定されているため、分類を増やしたい要求には素直に応えられない。
レガシーな構成が必要な場合、README は legacy ブランチの存在を示している。ただしこれは逃げ道であって移行先ではない。main と legacy は別物として扱うべきで、legacy の機能が main に戻ってくる保証はどこにも書かれていない。
比較対象としての Open WebUI、そしてライセンスと更新コスト
同じ問題領域には Open WebUI がある。両者の違いは接続の抽象度にある。chat-ui の現行ブランチは OpenAI 互換 API だけを話すと割り切り、`OPENAI_BASE_URL` と `/models` という2点で接続先を決める。プロバイダ固有の差異は OpenAI プロトコルに吸収させるという立場だ。Open WebUI は複数のバックエンドを直接扱う方向に広げており、対応する推論エンジンの幅はそちらが広い。裏を返せば、chat-ui は接続先を OpenAI 互換に揃えられるチームにとって設定項目が少なく、揃えられないチームにとっては選択肢が狭い。どちらが優れているかではなく、自分の推論基盤が `/models` を返せるかどうかで決まる。
ライセンスは Apache-2.0 である。派生物の配布や改変に寛容な条項を含むが、具体的な義務の範囲は利用形態によって変わるため、ここで法的な判断はしない。自組織の法務かライセンス本文で確認してほしい。
更新コストについては、リリース履歴が示す事実だけを置く。v0.9.5 が 2025-06-05、v0.9.6 が 2026-01-21、v0.10.0 が 2026-05-11 で、最新の push は 2026-09-09 である。約7か月から1年弱の間隔でマイナーが上がり、その間にも main は動いている。追従するなら `npm install` と `npm run build` を通す検証を定期的に回す必要があり、特に OpenRouter や Poe のような外部エンドポイントを `OPENAI_BASE_URL` に据えている場合、相手側の `/models` の応答が変わればモデル一覧が変わる。ここは自分の環境で確かめるしかない部分だ。
編集部の結論
採用を検討すべきなのは、OpenAI 互換のエンドポイントをすでに持っていて、MongoDB を運用に載せられるチームである。llama.cpp server や Ollama、OpenRouter を `OPENAI_BASE_URL` で指せるなら、チャット UI を自作するより速い。逆に、プロバイダ固有の SDK や GGUF の自動検出、埋め込みや Web 検索ヘルパーに依存した構成を前提にしている場合、このブランチは土台にならない。レガシー構成が必要なら legacy ブランチを見るべきで、main に移植できるとは限らない。導入前に確認するのは3点。`OPENAI_BASE_URL` の `/models` が期待どおりの一覧を返すか、`MONGODB_URL` を本番でどこに置くか、そして LLM Router を使うなら `LLM_ROUTER_ROUTES_PATH` に渡すルート方針 JSON を自分で用意できるかである。サンプルファイルはこのブランチに同梱されていない。
コミュニティノート