- JavaScript 81.9%
- CSS 10.2%
- HTML 3.7%
- Shell 3.2%
- Python 0.9%
- Other 0.1%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
All checks were successful
CI / Safe checks (pull_request) Successful in 5m21s
Container images / Build temporary amd64 candidates (push) Successful in 23m20s
Container images / Smoke-test App candidate (push) Successful in 1m3s
Container images / Smoke-test Whisper candidate (push) Successful in 45s
Container images / Publish immutable amd64 candidates (push) Successful in 1m21s
Release / Verify and publish release (push) Successful in 3m41s
|
||
| .forgejo | ||
| config | ||
| deploy | ||
| docker/whisper | ||
| docs | ||
| i18n | ||
| LICENSES | ||
| public | ||
| sandbox | ||
| scripts | ||
| src | ||
| tests | ||
| vendor/npm/sliced | ||
| .dockerignore | ||
| .gitattributes | ||
| .gitignore | ||
| agents.md | ||
| AGENTS.md | ||
| CHANGELOG.md | ||
| CODE_OF_CONDUCT.md | ||
| compose.standalone.yaml | ||
| compose.yaml | ||
| CONTRIBUTING.md | ||
| Dockerfile | ||
| eslint.config.js | ||
| GOVERNANCE.md | ||
| install.sh | ||
| LICENSE | ||
| NOTICE | ||
| package-lock.json | ||
| package.json | ||
| PRIVACY.md | ||
| README.de.md | ||
| README.md | ||
| SECURITY.md | ||
| server.js | ||
| THIRD_PARTY_INVENTORY.md | ||
| THIRD_PARTY_NOTICES.md | ||
| update.sh | ||
| web-tools.js | ||
ChatTLLX
Self-hosted, telemetry-free, and licensed under the GNU AGPL v3 or later.
ChatTLLX is a self-hosted chat interface for OpenAI-compatible LLM runtimes. It combines an everyday-ready multi-user chat with tools, documents, a calendar, long-term memories, and a personal OpenAI-compatible API for coding agents.
What you can do with it
| Area | Examples |
|---|---|
| Chat and response modes | streaming, administrator-defined modes, branches, search, and folders |
| Working with results | PDFs, Excalidraw and Mermaid diagrams, images, and HTML/CSS/JS/SVG/JSON artifacts |
| Personal context | freely categorized memories, attachments, calendar, tasks, and scheduled AI runs |
| Integration | personal API keys for OpenAI-compatible coding agents and your own scripts |
| Operations | accounts, roles, client-side encrypted chats, backups, PWA, and Forgejo CI/CD |
Built for local models
ChatTLLX is specifically optimized for capable local OpenAI-compatible runtimes. A stable prompt prefix, cache-safe relevant memories at the end of the message chain or an optional conversation-stable full-memory prefix for runtimes without embeddings, long-lived tool chains without an artificial round limit, SSE with recovery, and a power-saving client ensure that current local MoE models of the mid to larger performance class can achieve noticeably more in everyday use than a simple chat wrapper.
The goal is pragmatic: local models should be sufficiently good and pleasant to use for many people in research, writing, programming, documents, and personal organization. Expensive frontier models remain valuable for special cases, but they do not have to be the only option for every everyday task.
Get started in five minutes
Prerequisite: a fresh linux/amd64 Debian or Ubuntu host with a root shell. One command installs Docker when needed, pulls the prebuilt ChatTLLX image (and Whisper only when local speech is selected) from the Forgejo Container Registry, deploys the complete Compose stack, generates private secrets, and opens the path to browser-based onboarding. The host no longer compiles either image:
curl -fsSL https://forgejo.asxh.de/TLLX/CHAT-TLLX/raw/branch/main/install.sh | bash
If the current shell is not root, use | sudo bash instead. Root shells in minimal systems and LXC
containers do not need sudo to be installed.
The zero-prompt default detects a private IPv4 address and publishes direct HTTPS on port 5173 in the
local network. ChatTLLX creates a persistent local CA and server certificate automatically. The
browser shows a certificate warning on the first visit; after reviewing and continuing, onboarding
and browser encryption work without installing a separate proxy or local CA. If no private address
is available, the installer falls back to HTTPS on localhost and prints an SSH-tunnel command. A
domain or existing reverse proxy can still be selected explicitly when needed.
The completion message prints the random one-time setup token in a separate highlighted block. The
first account becomes the administrator after entering that token. A dedicated four-step assistant
then prepares the provider and first model, response modes and prompt, and local or remote
OpenAI-compatible speech transcription. It saves nothing before the final review. Connecting any
OpenAI-compatible API is the primary setup path. Optional Qwen and neutral starter presets open a
change preview before they can be applied; they are not a provider list and every value remains
editable.
See the
installation guide before using the command on an existing server.
The installed chattllx command provides status, scoped logs, lifecycle controls, and a read-only
doctor without contacting the model runtime. It also creates checksum-verified, age-encrypted full
backups and restores them with an automatic rollback boundary.
Administrators can check, start, and follow verified same-major updates from the dedicated Updates
screen. The same restricted host operator starts or removes the optional local speech container
when its database-backed admin mode changes, without exposing Docker or a root shell to the
application. The CLI remains available for recovery. Every update requires an
encrypted pre-update backup and refuses a release whose declared PostgreSQL schema does not exactly
match the running database.
New installations never expose the app over plaintext HTTP. An existing reverse proxy connects to the app over HTTPS and verifies the private ChatTLLX origin CA; managed Caddy installations use the same verified HTTPS hop internally. Existing installations keep their deployment configuration unchanged during updates.
For an unmanaged Docker or Portainer deployment, the self-contained
compose.standalone.yaml can be pasted directly as a stack. It creates
persistent named volumes, initializes its own secrets, serves direct HTTPS on port 5173, and prints
the one-time setup token in the init service log. It defaults to the stable amd64 :1 image
channel. Local Whisper is an opt-in speech-local Compose profile; remote speech and disabled
speech run no Whisper container. The checksum-verified installer above remains the recommended production path because it
also installs encrypted host backups, the operations CLI, and the restricted web-update operator.
How the project is structured
ChatTLLX is not a chat frontend in front of someone else's backend. The Node service owns the state, drives model and tool chains, stores results, and streams events to the browser. The browser remains a fast user interface with a local UI copy, while PostgreSQL and encrypted files are the durable source of truth in the Compose deployment. One PostgreSQL database keeps backup and transaction boundaries atomic, while domain schemas separate identity, workspace, configuration, automation, chat, and operational records.
The compact project overview explains the path of a message, a tool, and an artifact. The architecture describes the responsible modules and security boundaries in detail.
Why vanilla JavaScript?
The frontend deliberately uses native ES modules and DOM APIs instead of a general UI framework. ChatTLLX has long streams, changing tool phases, scrollable traces, and artifacts with their own DOM identity. Direct, small modules make this lifecycle visible and help avoid accidentally rebuilding running SVGs, images, or trace scroll positions during stream updates.
This is not a rejection of proven libraries: Excalidraw, Playwright, and Web Push are used where they solve concrete domain problems. For the general UI, however, vanilla JS avoids a second rendering and state layer, reduces client dependencies, and makes auth, caching, and progressive delivery easier to follow. The flip side is also deliberate: frontend modules must stay small, handle state explicitly, and be tested under streaming.
Documentation
Available in English (docs/en/) and German (docs/de/):
- Project overview: how a message, a tool, and a file travel through the system
- User guide: usage, features, and troubleshooting
- API and coding agent integration: personal keys, roles, tools, and context values
- Development: local setup, extension patterns, and test matrix
- Installation: one-command Compose setup, onboarding, and first-start checks
- Native to Compose migration: staged backup, cutover, and rollback
- Operations and deployment: secrets, backups, TLS, and runbooks
- Forgejo CI: safe checks, runner security, and branch protection
- Architecture: components, data storage, and security model
- Deployment configuration: all fields in
config/deployment.json - Instructions for coding agents: binding repository rules
Safe default checks
npm run lint
npm run test:docs
npm run test:licenses
npm run test:public
npm run test:unit
npm run test:ui
test:security, test:api, test:e2e, test:pdf:model, and test:pdf:routing require
services or credentials and can create test users, API keys, chats, or real model requests.
They belong only on controlled local or staging instances.
Security model
Chat contents are stored client-side end-to-end encrypted — immediately for new accounts and at the next password login for existing accounts. For durable chat storage the server only sees envelopes; folders, files, settings, memories, and scheduled prompts still have only server-side at-rest encryption at the current stage.
This is not a zero-knowledge inference system: the running server transiently processes the decrypted prompt to execute the model runtime and tools. An actively malicious operator could also modify the delivered browser JavaScript. The exact protection promise and the deliberate limits are described in the E2EE design.
Secrets, data/, ssl/, deployment configuration, and database exports never belong in commits
or support output.
Privacy and community
ChatTLLX contains no telemetry, analytics, crash reporting, tracking pixels, or hidden phone-home requests. Necessary operator-configured and user-triggered network connections are listed in PRIVACY.md.
Contributions are welcome. Please read CONTRIBUTING.md, the Code of Conduct, and the private-reporting guidance in SECURITY.md before submitting changes.