huggingface/chat-ui: a SvelteKit front end for any OpenAI-compatible endpoint
The open source codebase powering HuggingChat
At a glance
- What is it?
- Chat UI is the SvelteKit application behind HuggingChat, and the current branch speaks only to OpenAI-compatible APIs. It is a good fit if you want a self-hosted chat interface with MongoDB persistence and optional server-side routing, and the wrong fit if you need provider-specific integrations or a hosted product.
- Who is it for?
- Adopt Chat UI if you want a self-hosted SvelteKit chat front end pointed at an OpenAI-compatible endpoint, with MongoDB for history and the optional Omni router for model selection. Do not adopt it if you need the removed provider-specific integrations, GGUF discovery or embeddings, or if you want a managed service rather than something you operate.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What Chat UI solves and who ends up running it
Chat UI is the open source codebase behind HuggingChat, published by Hugging Face under Apache-2.0. It is a SvelteKit application that provides the browser interface for talking to a language model: conversation list, message thread, settings, file handling and stats. The README describes it plainly as "A chat interface for LLMs" and notes that it powers the HuggingChat app on hf.co/chat.
The audience is narrower than that description suggests. This is not a hosted product you sign up for. It is a repository you clone, configure with environment variables and run yourself, and the current branch has made a deliberate choice about what it will talk to. The README states that Chat UI supports OpenAI-compatible APIs only, via OPENAI_BASE_URL and the /models endpoint, and that provider-specific integrations such as the legacy MODELS env var, GGUF discovery, embeddings and web-search helpers have been removed. Anything that speaks the OpenAI protocol still works: the README lists llama.cpp server, Ollama and OpenRouter as examples.
So the person who benefits is someone who already has an OpenAI-compatible endpoint, whether a hosted router or a local server, and wants a maintained chat front end on top of it without writing the UI. If you were hoping for a multi-provider abstraction layer that normalizes each vendor's native API, this branch is not that, and the README points to the legacy branch for the older behaviour.
The request path: from browser to model through MongoDB
The architecture is a SvelteKit app with a server side that owns persistence and model calls. Chat history, users, settings, files and stats all live in MongoDB, and the README says you can point it at any MongoDB 6 or 7 deployment. When MONGODB_URL is not set, Chat UI falls back to an embedded MongoDB that persists to ./db, which is why the quickstart works without you installing a database first.
Model discovery is dynamic rather than hardcoded. Models are discovered from ${OPENAI_BASE_URL}/models, and you can optionally override their metadata through the MODELS env var as JSON5. Authorization uses OPENAI_API_KEY, with HF_TOKEN kept as a legacy alias. This means the model picker reflects whatever your endpoint advertises, which is convenient with a router that proxies many models and less convenient if your endpoint returns a list you do not want users to see.
The optional LLM Router is the most interesting piece of the design. When enabled, the UI exposes a virtual model alias, by default called Omni, and selecting it makes the server pick a route per message using a local heuristic. The README is explicit that no separate router service or selection model is called. Image inputs go to a multimodal route, MCP-tool-enabled requests go to an agentic route, and everything else goes to a default route. The router emits RouterMetadata immediately with the route and the actual model used, so the interface can show which model answered. If every model in the selected route fails, calls fall back to LLM_ROUTER_FALLBACK_MODEL. That is a small, legible mechanism rather than a black box, and the trade-off is that routing decisions are as good as the heuristic, not as good as a dedicated classifier.
Installing Chat UI and sending a first message
The README's quickstart pairs the Hugging Face Inference Providers router with a personal Hugging Face access token. Create a file named .env.local in the repository root with the base URL and the key. The README gives this exact shape, with the key shown as a placeholder:
OPENAI_BASE_URL=https://router.huggingface.co/v1
OPENAI_API_KEY=hf_************************If you would rather not send traffic to a hosted router, the README's provider table gives local alternatives. A llama.cpp server started with --server --api is reached at http://127.0.0.1:8080/v1, and the README notes that any string works as the key because llama.cpp ignores it. Ollama through its OpenAI-compatible bridge is reached at http://127.0.0.1:11434/v1 with the key set to ollama.
With the environment file in place, clone, install and start the dev server. The README gives these commands directly:
git clone https://github.com/huggingface/chat-ui
cd chat-ui
npm install
npm run dev -- --openThe dev server listens on http://localhost:5173 by default, and the browser should open to a working chat interface. For a production build the README points to npm run build and npm run preview.
If you want MongoDB outside your machine, the README offers two paths. A container is the shortest:
docker run -d -p 27017:27017 --name mongo-chatui mongo:latestThen set MONGODB_URL=mongodb://localhost:27017 in .env.local. The repository also ships a docker-compose.yml marked "For development only" that runs mongo:8 as a replica set and exposes ${LOCAL_MONGO_PORT:-27017}, with the same MONGODB_URL value expected in .env.local. Note the version difference: the README says MongoDB 6 or 7, while that compose file pins mongo:8 and the Dockerfile copies binaries from a mongo:7 stage. If you are choosing a database version, treat the README's statement as the supported range.
The Docker image that bundles its own database
The README documents an image called chat-ui-db that bundles MongoDB inside the container, which removes the separate database step entirely. The example mounts a named volume at /data and passes the same two environment variables as -e flags:
docker run \
-p 3000:3000 \
-e OPENAI_BASE_URL=https://router.huggingface.co/v1 \
-e OPENAI_API_KEY=hf_*** \
-v chat-ui-data:/data \
ghcr.io/huggingface/chat-ui-db:latestThe README states that all environment variables accepted in .env.local can be provided as -e flags. The Dockerfile confirms the mechanism: an INCLUDE_DB build argument selects between a stage that copies the mongo binaries and one that does not, and the bundled variant sets MONGODB_URL=mongodb://localhost:27017 inside the image. The build stage also sets BODY_SIZE_LIMIT=15728640, which is the upload ceiling you inherit unless you override it.
This is the option to pick for a single-node deployment or a demo. It is a poor fit for anything where you want the database to survive independently of the application container, scale separately, or be backed up by your existing MongoDB tooling, because the data lives in the volume attached to that one container.
Where Chat UI is the wrong tool
The removal of provider-specific integrations is the biggest constraint, and it is a design decision rather than a bug. If your model provider does not expose an OpenAI-compatible /models endpoint, Chat UI cannot discover your models and you are relying on the MODELS override at best. Projects that need GGUF discovery, embeddings or built-in web search will not find them here; the README says those were removed and points to the legacy branch.
The router configuration is the second sharp edge. The README states that routes are supplied through LLM_ROUTER_ROUTES_PATH as a JSON array, that each entry needs name, description, primary_model and optional fallback_models, and that the recognized route names are default, multimodal and agentic. It also states that no sample file ships with this branch, so you must create the JSON yourself, for example at config/routes.chat.json. There is no documented schema beyond the field list, which means the first attempt is guesswork until you read the source. If you wanted routing that improves with feedback or learns from outcomes, note that the heuristic is local and static.
Operationally, MongoDB is not optional in spirit even though the embedded fallback exists. The embedded database persists to ./db, which is fine on a laptop and awkward in a container without a volume. And because this is a front end you operate, you own upgrades, backups, authentication configuration and rate limiting. Nothing in the README describes a built-in multi-tenant access model; the data-sharing toggle controlled by PUBLIC_APP_DATA_SHARING is about opting users into sharing with model creators, not about isolating tenants from each other.
Chat UI compared with Open WebUI
The comparison people reach for is Open WebUI, and the difference is mostly about what each project treats as its core. Open WebUI is built around being a complete self-hosted chat product with its own user management, model backends and feature set. Chat UI is the interface layer that Hugging Face runs in production for HuggingChat, and this branch has narrowed its scope to the OpenAI protocol on purpose.
That shows up in the mechanics. Chat UI discovers models from ${OPENAI_BASE_URL}/models, so the model catalog belongs to whatever endpoint you point at, and its differentiator is the optional Omni alias with local route selection and immediate RouterMetadata. The routing is heuristic and in-process rather than a separate service. If you want a broad, batteries-included deployment where the application owns more of the stack, Chat UI's deliberate reduction will feel like missing pieces. If you already have an OpenAI-compatible gateway and want a maintained SvelteKit front end with a thin routing layer, the narrowed surface is the point.
One practical consequence: because Chat UI is SvelteKit, the front end is Svelte components rather than React. Teams with a React codebase and a desire to fork the UI heavily should weigh that before starting, since the search interest around React and shadcn chat interfaces reflects a different ecosystem.
Maintenance, licence and upgrade cost
The repository is not archived, and the last push was on 2026-09-09, which is recent. Releases are less frequent than commits: v0.10.0 was published on 2026-05-11, v0.9.6 on 2026-01-21 and v0.9.5 on 2025-06-05. The package.json in the repository declares version 0.20.0, which does not line up with the published release tags, so if you track versions, pin to a commit or a release tag rather than assuming the package version reflects a release.
Upgrade cost is shaped by the removal of the legacy integrations. Anyone migrating from an older deployment that used the legacy MODELS env var, GGUF discovery or the other removed helpers should expect real work: the README directs them to the legacy branch, and the current branch expects an OpenAI-compatible endpoint instead. Beyond that, the stack is conventional and the scripts are the usual ones: npm run check for svelte-check, npm run lint for prettier and eslint, npm test for the server and SSR vitest projects, and npm run test:e2e for Playwright. The Dockerfile builds on node:24 and installs dotenv-cli, so the runtime baseline is Node 24.
The licence is Apache-2.0, which permits commercial use and modification with the usual obligations around notices and changed files. This is a statement about the licence text, not legal advice; if you are embedding the project in a product, have your own counsel read the LICENSE file in the repository.
Editorial conclusion
Adopt Chat UI if you want a self-hosted SvelteKit chat front end pointed at an OpenAI-compatible endpoint, with MongoDB for history and the optional Omni router for model selection. Do not adopt it if you need the removed provider-specific integrations, GGUF discovery or embeddings, or if you want a managed service rather than something you operate. Verify first that your endpoint exposes /models, that your MongoDB is version 6 or 7, and that you are willing to write your own routes policy JSON, because no sample ships with this branch.
Frequently asked questions
What is huggingface/chat-ui?
It is the open source SvelteKit codebase that powers the HuggingChat app on hf.co/chat, described in the README as a chat interface for LLMs. It stores conversations in MongoDB and talks to models through an OpenAI-compatible API.
How is huggingface/chat-ui different from Open WebUI?
Chat UI is the interface layer Hugging Face runs for HuggingChat and this branch supports OpenAI-compatible APIs only, with models discovered from ${OPENAI_BASE_URL}/models. Its distinctive piece is the optional Omni alias, which selects a route locally using a heuristic rather than calling a separate router service.
What is the best chat UI?
That depends on the endpoint you already run. Chat UI fits teams with an OpenAI-compatible API and MongoDB, since it discovers models from /models and persists history in MongoDB 6 or 7. If you need provider-specific integrations, GGUF discovery or embeddings, the README says those were removed from this branch.
What is the purpose of a chat UI like huggingface/chat-ui?
It provides the browser interface for talking to a language model, including the conversation list, message thread, settings and file handling. In Chat UI's case the README describes it as a chat interface for LLMs, with history, users, settings, files and stats stored in MongoDB.
What is new in the current huggingface/chat-ui branch?
The README states that Chat UI now supports OpenAI-compatible APIs only, via OPENAI_BASE_URL and the /models endpoint, and that provider-specific integrations such as the legacy MODELS env var, GGUF discovery, embeddings and web-search helpers were removed. It also documents the optional Omni alias, which picks a route locally using a heuristic.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/huggingface-chat-ui)
Community notes