huggingface/chat-ui : une interface de chat qui ne parle qu'un seul protocole
The open source codebase powering HuggingChat
En bref
- De quoi s’agit-il ?
- Le code derrière HuggingChat est un projet SvelteKit sous licence Apache-2.0 qui a fait un choix radical : ne supporter que les API compatibles OpenAI. Ce choix simplifie l'intégration et supprime toute une catégorie de code.
- À qui s’adresse-t-il ?
- À adopter si vous voulez une interface de chat LLM prête à l'emploi et que votre backend parle le protocole OpenAI. À écarter si vous dépendez d'intégrations propres à un fournisseur, de la découverte GGUF ou d'embeddings intégrés : ce code a été retiré.
- Puis-je l’utiliser commercialement ?
- Oui. Apache-2.0 est une licence permissive : vous pouvez utiliser, modifier et vendre un logiciel qui en dépend, à condition de conserver les mentions de droit d’auteur et de licence.
- Est-il encore maintenu ?
- Oui. Le dépôt a reçu de nouveaux commits au cours des dernières 24 heures.
- En quel langage est-il écrit ?
- Principalement TypeScript, d’après les statistiques de langage de GitHub.
Ces réponses reposent sur les données GitHub du projet (dernière synchronisation le 15 septembre 2026) et sur notre analyse. Elles ne constituent pas un avis juridique.
ANALYSE OPEN SOURCE APPROFONDIE
Le problème que résout ce dépôt, et pour qui
Écrire une interface de chat pour un modèle de langage n'est pas difficile. Écrire une interface qui gère l'historique des conversations, les comptes utilisateurs, le téléversement de fichiers, les statistiques d'usage et le partage de données, c'est un autre exercice. Le README de chat-ui annonce la couleur : c'est l'application qui fait tourner HuggingChat sur hf.co/chat. Le projet s'adresse donc en priorité à des équipes qui veulent héberger leur propre interface de discussion sans repartir de zéro, et qui acceptent de s'appuyer sur MongoDB pour la persistance.
Le périmètre est clair. Le README précise que l'historique des conversations, les utilisateurs, les réglages, les fichiers et les statistiques vivent tous dans MongoDB. Il ne s'agit pas d'un composant que l'on insère dans une application existante, mais d'une application complète avec son propre backend SvelteKit. Une équipe qui cherche uniquement un widget de chat à embarquer dans un produit tiers trouvera ici beaucoup plus de surface que nécessaire, et devra composer avec une base de données qu'elle n'avait peut-être pas prévue.
Un seul protocole en entrée : le choix structurant
La note en tête du README est sans ambiguïté : Chat UI ne supporte que les API compatibles OpenAI, via OPENAI_BASE_URL et le point de terminaison /models. Les intégrations propres à chaque fournisseur ont été retirées, et la liste citée est explicite : l'ancienne variable MODELS comme mécanisme principal, la découverte GGUF, les embeddings, les assistants de recherche web. Le code hérité reste accessible sur la branche legacy, ce qui indique que la rupture est assumée et datée.
En contrepartie, tout service qui parle le protocole OpenAI fonctionne sans adaptation. Le README donne un tableau de combinaisons : le routeur Hugging Face Inference Providers sur https://router.huggingface.co/v1, un serveur llama.cpp sur http://127.0.0.1:8080/v1, Ollama via son pont compatible sur http://127.0.0.1:11434/v1, OpenRouter, ou encore Poe. Dans le cas de llama.cpp, le README note que la clé est ignorée et qu'une chaîne quelconque suffit. C'est le genre de détail qui évite une heure de doute au premier lancement.
Cette uniformité a un coût. Une fonctionnalité qui n'existe que chez un fournisseur précis, et qui ne passe pas par le protocole OpenAI, n'a plus de chemin d'accès dans cette base de code. Il faut soit l'ajouter soi-même, soit renoncer.
MongoDB, ou la base embarquée pour le développement
La persistance est le point où l'installation se complique. chat-ui cible MongoDB 6 ou 7, et le README propose trois voies. La première est un cluster Atlas : on ajoute son adresse IP à la liste d'accès réseau, on crée un utilisateur de base de données, on colle la chaîne de connexion dans MONGODB_URL et on garde MONGODB_DB_NAME=chat-ui par défaut, ou on le change selon l'environnement. La deuxième est un conteneur local, avec la commande docker run -d -p 27017:27017 --name mongo-chatui mongo:latest, puis MONGODB_URL=mongodb://localhost:27017.
La troisième voie est la plus intéressante pour évaluer le projet rapidement. Quand MONGODB_URL n'est pas défini, Chat UI bascule sur un MongoDB embarqué qui persiste dans ./db. On peut donc lancer l'application et discuter sans installer quoi que ce soit côté base. C'est un vrai confort pour un premier essai, mais aussi un piège si l'on oublie de définir la variable en production : le README ne décrit pas de garde-fou qui empêcherait ce repli de s'activer sur un serveur mal configuré. À vérifier dans votre déploiement.
Mise en route : les commandes et les clés
Le chemin le plus court passe par un fichier .env.local contenant deux lignes : OPENAI_BASE_URL=https://router.huggingface.co/v1 et OPENAI_API_KEY=hf_************************. Le README signale que HF_TOKEN reste un alias hérité, mais que OPENAI_API_KEY est la forme préférée. Ensuite, git clone, cd chat-ui, npm install, puis npm run dev -- --open. Le serveur de développement écoute sur http://localhost:5173. Pour une build de production, ce sont npm run build et npm run preview.
Il existe une image Docker optionnelle, chat-ui-db, qui embarque MongoDB dans le conteneur. L'exemple du README expose le port 3000, passe OPENAI_BASE_URL et OPENAI_API_KEY en variables -e, et monte un volume chat-ui-data sur /data pour la persistance. Toutes les variables acceptées dans .env.local peuvent être fournies en -e.
Le volet apparence tient dans quatre variables publiques : PUBLIC_APP_NAME, PUBLIC_APP_ASSETS (qui détermine où trouver logos et favicons dans static/$PUBLIC_APP_ASSETS, avec chatui et huggingchat comme options documentées), PUBLIC_APP_DESCRIPTION, et PUBLIC_APP_DATA_SHARING. Cette dernière, réglée à 1, ajoute dans les paramètres utilisateur une option de partage des données avec le créateur du modèle. C'est une brique de conformité, pas un détail cosmétique.
Le routeur LLM : un heuristique local, pas un modèle de sélection
La fonctionnalité la plus singulière du projet est le routeur côté serveur. Le README insiste sur un point : il s'agit d'un heuristique local, aucun service de routage séparé ni modèle de sélection n'est appelé. L'interface expose un alias de modèle virtuel, Omni par défaut, et quand l'utilisateur le choisit, l'application décide de la route en fonction de signaux simples : une image en entrée part vers une route multimodal, une requête avec outils MCP activés part vers une route agentic, tout le reste va vers default.
La configuration repose sur un fichier JSON de politique, désigné par LLM_ROUTER_ROUTES_PATH. Point important : aucune politique d'exemple n'est fournie dans cette branche, il faut écrire soi-même un tableau JSON et le versionner, par exemple dans config/routes.chat.json. Chaque entrée porte un name, une description, un primary_model et éventuellement des fallback_models. Le routeur ne reconnaît que les noms de route default, multimodal et agentic. Si tous les modèles d'une route échouent, l'appel se replie sur LLM_ROUTER_FALLBACK_MODEL.
L'alias lui-même se paramètre avec PUBLIC_LLM_ROUTER_ALIAS_ID (omni par défaut), PUBLIC_LLM_ROUTER_DISPLAY_NAME (Omni) et une URL de logo facultative. Le comportement annoncé est le suivant : sélection locale de la route, émission immédiate de métadonnées indiquant la route et le modèle réellement utilisé, puis diffusion en flux depuis le modèle choisi via OPENAI_BASE_URL. Cette transparence sur le modèle effectivement appelé est utile, mais elle repose entièrement sur la qualité de vos propres règles de routage.
Là où le projet vous laisse à mi-chemin
Le routeur illustre la principale faiblesse de cette version : la documentation décrit le mécanisme mais ne fournit pas le matériel de départ. Pas de fichier de routes d'exemple, donc pas de référence pour savoir à quoi ressemble une entrée valide au-delà des quatre clés nommées. Il faut deviner le format exact, puis le déboguer à l'exécution.
Le même schéma se retrouve sur les modèles. Ils sont découverts depuis ${OPENAI_BASE_URL}/models, et le README mentionne une surcharge possible des métadonnées via la variable MODELS en JSON5. Mais si votre endpoint expose un catalogue incomplet ou des identifiants peu lisibles, c'est à vous de construire la surcharge. Rien n'est fourni.
Enfin, la suppression des embeddings et des assistants de recherche web signifie que ces capacités ne sont plus dans le périmètre. Un projet qui en dépend doit les réimplémenter ou les déléguer à un service externe. Ce n'est pas un défaut en soi, c'est une frontière, et elle est explicite dans le README.
Face à LibreChat et aux autres interfaces
L'alternative la plus évidente pour un lecteur qui cherche une interface de chat auto-hébergée est LibreChat, qui vise plusieurs fournisseurs natifs plutôt qu'un protocole unique. La différence d'approche est nette : chat-ui concentre le support sur le protocole OpenAI et supprime le code spécifique aux fournisseurs, tandis qu'une interface multi-fournisseurs conserve des adaptateurs pour chacun. Le premier choix réduit la surface de maintenance et la rend prévisible, au prix de l'impossibilité d'exploiter une API propriétaire sans écrire l'adaptateur manquant. Le second accepte plus de code à maintenir pour couvrir davantage de backends.
Cette comparaison vaut aussi pour l'usage : si votre infrastructure est déjà exposée derrière un endpoint compatible OpenAI, la contrainte de chat-ui ne vous coûte rien. Si vous devez jongler entre plusieurs SDK et formats d'authentification, elle vous coûtera du travail.
Licence, mises à jour et coût de suivi
Le dépôt est publié sous Apache-2.0, une licence permissive qui autorise l'usage commercial et la modification, avec les obligations habituelles de conservation des mentions de licence et de copyright. Ce texte ne constitue pas un avis juridique : faites relire votre cas d'usage si la redistribution est au programme.
Le rythme de publication observable est irrégulier. Trois versions figurent dans les informations fournies : v0.9.5 en juin 2025, v0.9.6 en janvier 2026, puis v0.10.0 en mai 2026. Le dernier envoi sur la branche main est daté de septembre 2026, soit plusieurs mois après la dernière version. Une telle cadence signifie que suivre la branche main peut exposer à des changements non étiquetés, et que se caler sur les tags est plus prudent pour un déploiement stable.
Le coût de mise à jour tient surtout à la variable MODELS et au format des politiques de routage. Ces deux points sont des points de rupture possibles entre versions : le README indique d'ailleurs que l'ancienne variable MODELS a changé de rôle, passant de mécanisme principal à simple surcharge de métadonnées. Une montée de version mérite donc une relecture du .env et du fichier de routes avant déploiement.
Conclusion éditoriale
À adopter si vous voulez une interface de chat LLM prête à l'emploi et que votre backend parle le protocole OpenAI. À écarter si vous dépendez d'intégrations propres à un fournisseur, de la découverte GGUF ou d'embeddings intégrés : ce code a été retiré. Avant de déployer, vérifiez trois choses concrètes : que votre endpoint expose bien /models, que votre déploiement MongoDB est en version 6 ou 7, et que votre politique de routes JSON respecte les noms default, multimodal et agentic attendus par le routeur.
Notes de la communauté