LinuxChat is a Linux-first native desktop AI chat client built with C, GTK4, GLib, SQLite, and a small Python provider layer.
It is intended to be a native Linux desktop application rather than a browser shell, Electron wrapper, or web-first frontend. The project focuses on local state, direct desktop integration, inspectable source code, and a runtime model that remains understandable to developers working close to the system.
LinuxChat is currently an actively iterated engineering project. It is already usable for real local work, provider-backed chat, streamed replies, reasoning-aware display, attachment-aware prompting, a built-in Skills system, local tool integration for supported provider paths, and SQLite-backed persistence, but it should still be understood as a fast-moving native client rather than a frozen end-user product.
- English:
README.md - 简体中文:
README.zh-CN.md - Config guide (English):
config.md - 配置说明(简体中文):
config.zh-CN.md
LinuxChat is:
- a GTK-native Linux desktop AI client
- a C-first codebase with a small Python provider layer
- a local-state application that stores its own runtime data under the user configuration directory
- a hackable engineering project meant to stay inspectable and modifiable
- a desktop-first application that tries to remain close to Linux workflow expectations
LinuxChat is not:
- a web app packaged as a native shell
- a browser-dependent frontend
- a fully stabilized cross-platform product
- a closed provider-only interface with no local workflow awareness
The current codebase already supports:
- GTK4 native desktop UI
- multiple conversations
- streamed assistant replies
- streamed reasoning / thinking display for supported provider flows
- safer local tool retry behavior after blocked commands
- built-in provider support
- local file attachments
- local file and command tool integration for supported provider paths
- SQLite-backed durable storage
- persistent lightweight UI preference storage
- advanced appearance config through
config.json - desktop installation through
make/sudo make install
Current persistence paths include:
~/.config/LinuxChat/SQL/conversations.db
~/.config/LinuxChat/SQL/preferences.db
LinuxChat also maintains a persistent local workspace rooted at:
~/.config/LinuxChat/
This workspace may contain:
- runtime configuration
- Python virtual environment state
- SQLite databases
- formatting guidance files
- custom user Skills
- state files
- advanced config files
The application also writes a built-in formatting guide to:
~/.config/LinuxChat/USE.md
That file is used as part of prompt shaping for safer and more consistent model output formatting.
User-defined custom Skills may also be placed in:
~/.config/LinuxChat/Skills/
Only *.md files from that directory are loaded, and they are injected in
filename order.
A typical source tree looks like this:
LinuxChat/
├── Documentation/
├── Images/
├── Makefile
├── LICENSE
├── README.md
├── README.zh-CN.md
├── config.default.json
├── config.md
├── config.zh-CN.md
├── packaging/
├── resources/
└── src/
Important directories:
src/- main native C sources
- public headers
- provider Python adapters
- shared Python provider transport/helpers
resources/- GTK CSS
- PNG icons
- runtime visual assets
packaging/- desktop entry and packaging-related files
Documentation/- developer-facing architecture, module, flow, risk, and extension docs
LinuxChat currently provides:
- GTK4 desktop interface written mainly in C
- user / assistant / system message rendering
- copy button on assistant replies
- per-reply elapsed time display
- visible placeholder state before streamed content arrives
- streamed answer display with progressively revealed text
- streamed reasoning / thinking display for supported providers
- light / dark theme switching
- runtime language switching without restart
- desktop launcher integration
LinuxChat currently supports:
- multiple conversations
- sidebar conversation switching
- archive/delete style conversation flow
- local chat persistence
- local reload on next app start
- SQLite-backed durable history
- lightweight settings persistence via SQLite
LinuxChat currently includes bundled provider-side adapters for:
- GPT / OpenAI
- Claude / Anthropic
- Gemini
- DeepSeek
- Qwen
- GLM
- Moonshot / Kimi
These provider adapters are Python scripts launched by the native frontend.
LinuxChat uses a two-layer Skills model:
- built-in formatting/runtime guidance at
~/.config/LinuxChat/USE.md - user-defined custom skills under
~/.config/LinuxChat/Skills/
Behavior:
USE.mdremains the mandatory built-in formatting/output policy- custom user Skills are loaded from
~/.config/LinuxChat/Skills/*.md - files are read in filename order, so users can control order with names such
as
1.md,2.md,10-project-rules.md - if the Skills directory is empty, LinuxChat does not inject extra user skill content, avoiding unnecessary token usage
- the built-in guidance also includes safer blocked-tool retry behavior and code-fence formatting rules
The direct-provider path is designed around streamed output. In practice this means:
- incremental provider events are emitted while the reply is still being generated
- reasoning and normal answer text can both be surfaced progressively when the provider path supports them
- the UI reveals content progressively instead of waiting on a blank bubble
For supported direct-provider paths, LinuxChat includes a host-side local tool layer with controlled operations such as:
read_filewrite_fileappend_filelist_dirrun_command
LinuxChat also includes blocked-tool retry guidance so a denied command does not necessarily waste the entire turn. The model is encouraged to switch to a legal read-only or narrower alternative instead of immediately ending the task.
LinuxChat currently supports:
- local file attachment selection from the desktop UI
- attachment content injection for supported file types
- provider-side prompt packaging with file-aware context
- guard rails against blindly treating binary content as normal text
LinuxChat supports an advanced runtime config file at:
~/.config/LinuxChat/.config/config.json
That file can override:
- startup theme mode
- colors
- transparency
- border visibility
- window radius
- custom CSS
- a small set of advanced appearance flags
See config.md and config.zh-CN.md for the full field reference.
LinuxChat expects a Linux environment with:
- GTK4 development files
- GLib / GObject / Gio development files
- Pango development files
- SQLite3 development files
- Python 3 with
venv - a C compiler such as
gcc pkg-config
sudo pacman -S --needed base-devel gtk4 glib2 pango cairo gdk-pixbuf2 graphene harfbuzz sqlite desktop-file-utils shared-mime-infosudo dnf install -y gcc make gtk4-devel glib2-devel pango-devel cairo-devel gdk-pixbuf2-devel graphene-devel sqlite-devel desktop-file-utilssudo apt install -y build-essential pkg-config libgtk-4-dev libglib2.0-dev libcairo2-dev libpango1.0-dev libgdk-pixbuf-2.0-dev libgraphene-1.0-dev libsqlite3-dev desktop-file-utilsmakeThis does two things:
- prepares
~/.config/LinuxChat/env - builds the native launcher binary
make runsudo make installInstall behavior:
- installs the launcher under
$(PREFIX)/bin - installs the runtime binary, Python provider scripts, resources, and headers
- installs desktop integration and icon files
- seeds user runtime config,
USE.md, andskill.jsonunder the target desktop user's~/.config/LinuxChat - installs README/config/developer docs under the doc directory selected by the Makefile
sudo make uninstallThis removes installed application files, but intentionally does not remove the
user's ~/.config/LinuxChat runtime data.
Start here if you want to modify the code base:
Documentation/index.rstDocumentation/architecture.rstDocumentation/getting_started_for_developers.rstDocumentation/contributing_style.rst
Subsystem documentation is organized under:
Documentation/app/Documentation/api_manager/Documentation/storage/Documentation/settings_db/Documentation/attachments/Documentation/commands/Documentation/main/Documentation/provider_common/Documentation/providers/
LinuxChat is distributed under the GNU General Public License v3.0 only. See
LICENSE for the full license text.