Skip to main content
TouchAI follows a strict two-layer architecture. The Vue 3 frontend handles all UI rendering and business logic visible to the user. The Tauri Rust backend owns OS integration — global shortcuts, window management, system tray, autostart, file system access, and MCP client orchestration. The two layers communicate exclusively through Tauri’s IPC command system.

Layer overview

LayerTechnologyResponsibility
FrontendVue 3 · TypeScript · Pinia · Drizzle ORMUI, AI service calls, state management, local DB
BackendRust · Tauri 2OS APIs, window lifecycle, MCP client, shortcuts
IPC boundaryTauri commands (invoke)Type-safe bridge between the two layers
PersistenceSQLite via tauri-plugin-sqlChat history, settings, MCP server configs

Frontend (src/)

Views (src/views/)

Each top-level view maps to a dedicated Tauri window or overlay panel.
ViewPurpose
SearchView/Main command-bar window (750 × 60 px, expands to max 700 px height)
SettingsView/Application settings and MCP server management
PopupView/Context-aware inline popup for selected text
TrayView/Lightweight panel anchored to the system-tray icon

Services (src/services/)

Services are singleton classes or composable modules that encapsulate domain logic and Tauri API calls.
ServiceResponsibility
AiService/Manages the AI provider connection, streams completions, and runs the agent loop for MCP tool execution
EventService/Tauri event bus wrapper — enables cross-window messaging
LoggerService/Structured logging layer over tauri-plugin-log
NativeService/Clipboard, file system, and other native OS helpers
PopupService/Controls the lifecycle and positioning of the popup window
StartupService/Bootstraps the application on first load (initial settings, shortcut registration)

Stores (src/stores/)

Pinia is used for reactive global state. Two stores are defined:
  • settings.ts — persisted user preferences (AI provider, model, theme, shortcut)
  • mcp.ts — runtime MCP server list and connection status

Other frontend modules

DirectoryContents
src/components/Shared, reusable UI components built with Reka UI and TailwindCSS v4
src/composables/Vue composables for shared reactive logic
src/database/Drizzle ORM schema (schema.ts) and query helpers
src/router/Vue Router configuration mapping routes to views
src/lib/Low-level utilities and third-party library wrappers
src/utils/Pure helper functions

Path aliases

Vite resolves short import paths defined in vite.config.ts:
'@'src/
'@components'src/components/
'@composables'src/composables/
'@database'src/database/
'@services'src/services/
'@styles'src/styles/
'@types'src/types/
'@utils'src/utils/

Backend (src-tauri/src/)

Commands (src-tauri/src/commands/)

Tauri IPC command handlers — each file exposes one or more #[tauri::command] functions callable from the frontend via invoke().
FileExposed commands
autostart.rsEnable / disable OS autostart
mcp.rsStart, stop, and query MCP server connections
paths.rsResolve app data and config directory paths
quick_search.rsDrive the quick-search provider
shortcut.rsRegister and update the global keyboard shortcut
window.rsShow, hide, and reposition application windows

Core (src-tauri/src/core/)

Domain logic that the command handlers delegate to.
ModuleContents
mcp/client_manager.rs — pool of active MCP client connections; client.rs — single-session MCP client over stdio, SSE, or streamable HTTP; types.rs — shared MCP types
search/manager.rs — search orchestrator; assets.rs — indexed asset catalogue; provider_everything.rs — Everything SDK integration; types.rs — result types
system/autostart.rs, shortcut.rs, paths.rs, logging.rs, assets.rs — OS-level helpers
window/Sub-modules for popup/, search/, settings/, tray/ window controllers plus resize.rs for dynamic height adjustment
setup.rsTauri app initialisation — plugin registration and startup sequence

Key architectural patterns

Tauri IPC

The frontend never calls OS APIs directly. Every privileged operation goes through a typed invoke() call:
import { invoke } from '@tauri-apps/api/core'

const result = await invoke<string>('get_app_data_dir')
On the Rust side the corresponding handler is declared with #[tauri::command] and registered in setup.rs.

Agent loop (MCP tool execution)

AiService implements a multi-turn agent loop: it sends a user message to the AI provider, receives a response that may contain tool-call requests, forwards those calls to the appropriate MCP server via NativeService / the mcp command, collects results, and feeds them back into the next completion turn until the model returns a final text response.

Cross-window events

Tauri supports multiple independent webview windows. EventService wraps @tauri-apps/api/event to emit and listen for named events, allowing SearchView, PopupView, and TrayView to stay in sync without sharing a process.

Persistence

Drizzle ORM generates SQL migrations from src/database/schema.ts. At runtime tauri-plugin-sql executes queries against the SQLite database at data/touchai.db. The Drizzle sqlite dialect is used; no server-side database is required.

Window configuration

The main window is defined in src-tauri/tauri.conf.json:
PropertyValueEffect
width / minWidth750 pxFixed horizontal size
height / minHeight60 pxCollapsed (search-bar only) state
maxHeight700 pxExpanded (with results/chat) state
transparenttrueFrameless, background rendered by Vue
decorationsfalseNo OS window chrome
shadowfalseShadow drawn in CSS
alwaysOnToptrueFloats above all other applications
skipTaskbartrueHidden from taskbar / dock
visiblefalseStarts hidden; shown by shortcut or tray
centertrueInitially positioned at screen centre
The window core module (src-tauri/src/core/window/resize.rs) dynamically adjusts the height between the minimum and maximum bounds as the content grows.

Build chunks

Vite splits the frontend into named chunks to keep initial load fast:
ChunkContents
vendor-frameworkvue, vue-router, pinia
vendor-uireka-ui, vue-sonner
vendor-aiopenai, @anthropic-ai/sdk
vendor-markdownmarkstream-vue, markdown-it-emoji
vendor-diagramsmermaid, katex
vendor-monacomonaco-editor
vendor-tauriAll @tauri-apps/* packages

Build docs developers (and LLMs) love