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, OpenCode integration, attachment-aware prompting, and SQLite-backed persistence, but it should still be understood as a fast-moving native client rather than a frozen end-user product.
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
- direct built-in provider support
- OpenCode-backed model discovery and execution
- local file attachments
- local file and command tool integration for supported provider paths
- SQLite-backed durable storage
- persistent lightweight UI preference storage
- desktop installation through
make/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
- 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.
A typical source tree looks like this:
LinuxChat/
├── Documentation/
├── Makefile
├── LICENSE
├── README.md
├── config.default.json
├── 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
- incremental streamed reply reveal
- 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
These provider adapters are Python scripts launched by the native frontend.
LinuxChat also supports an OpenCode path through the local CLI, including workflow based around commands such as:
opencode modelsopencode run
This allows LinuxChat to discover and use locally configured OpenCode models from the native UI.
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
- the UI reveals content progressively
- the user sees visible response progress 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
This means LinuxChat can provide a real local tool bridge instead of allowing a model to merely pretend it accessed local files or commands.
LinuxChat currently supports:
- attaching local files to the active conversation
- extracting text-like attachment context into prompts
- bounded attachment handling in UI logic
- explicit instruction not to fake image understanding when image bytes were not actually inspected
The current install flow uses a layout based on /usr/local/bin:
- launcher:
/usr/local/bin/linuxchat-cgtk
- native compiled binary:
/usr/local/bin/linuxchat-cgtk-bin
- installed resources:
/usr/local/bin/resources/
- installed bundled source/helpers:
/usr/local/bin/src/
This layout is used so the launcher, binary, resources, and bundled helper scripts can continue to resolve each other through stable local paths.
LinuxChat also creates and uses a Python virtual environment at:
~/.config/LinuxChat/env
That environment is used for bundled provider helper scripts and their Python dependencies.
- C11
- GTK4
- GLib / GObject / GIO
- Pango
- SQLite3
- GTK CSS styling through
resources/app.css
- Python 3
- OpenCode CLI
openaianthropic- HTTPS / JSON request flows for Gemini, DeepSeek, Qwen, and GLM
- streamed provider-to-frontend event flow
The current resource path is PNG-based for application/UI imagery.
sudo pacman -S --needed base-devel gtk4 glib2 pango cairo gdk-pixbuf2 graphene harfbuzz sqlite desktop-file-utils shared-mime-info
sudo dnf install -y gcc make gtk4-devel glib2-devel pango-devel cairo-devel gdk-pixbuf2-devel graphene-devel sqlite-devel desktop-file-utils
sudo 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-utils
opencodeavailable inPATH
- Python 3
venv- valid API keys depending on provider, for example:
OPENAI_API_KEYANTHROPIC_API_KEYGEMINI_API_KEYorGOOGLE_API_KEYDEEPSEEK_API_KEYDASHSCOPE_API_KEYorQWEN_API_KEYZAI_API_KEY,GLM_API_KEY, orZHIPUAI_API_KEY
make
Run from the build tree:
./linuxchat-cgtk
sudo make install
LinuxChat uses local configuration under:
~/.config/LinuxChat/
Advanced appearance and theme behavior are controlled through:
~/.config/LinuxChat/.config/config.json
That JSON configuration is intended for advanced runtime customization such as:
- theme colors
- transparency-related appearance values
- border visibility
- radius values
- optional CSS injection
- selected advanced UI behavior flags
The shipped repository also includes:
config.default.json
which acts as the baseline default template.
The main developer documentation lives under:
Documentation/
Recommended reading order for new developers:
Documentation/index.rstDocumentation/architecture.rstDocumentation/getting_started_for_developers.rstDocumentation/contributing_style.rst
After that, continue with module-specific documentation such as:
Documentation/app/Documentation/api_manager/Documentation/storage/Documentation/settings_db/Documentation/attachments/Documentation/commands/Documentation/main/Documentation/provider_common/Documentation/providers/
The documentation tree is intended to explain:
- project architecture
- module responsibilities
- startup and runtime flow
- persistence flow
- streaming flow
- extension paths
- high-risk code paths
- maintenance expectations
- modification style rules
Source files also carry inline English comments and GPL-3.0 SPDX headers.
This project is aimed at developers who want:
- a native Linux desktop AI client
- local persistence
- a codebase that can actually be read and modified
- less web-stack weight
- more direct control over packaging, resources, local tools, and runtime behavior
At the same time, developers should expect:
- active iteration
- evolving structure in some areas
- continued rendering and performance tuning work
- ongoing cleanup and documentation expansion
- compatibility considerations around legacy persistence paths
To keep this README honest, the current project still has important limits:
- Linux is the primary target platform
- the application is still closer to an actively developed engineering project than a frozen polished product
- direct-provider behavior depends on valid API keys and working Python dependencies
- OpenCode usage depends on the local OpenCode installation and model setup
- rendering and streaming behavior are still under active iteration
- some rich-content and edge-case rendering paths are still evolving
- local tool behavior is intentionally constrained by safety boundaries and allowed-root policy
LinuxChat is already usable, but it should still be treated as a project in active engineering motion.
LinuxChat is licensed under GPL-3.0-only. See:
LICENSE
for the full license text.


