How llmfit's Tauri Desktop Application Integrates with the Core Rust Library

The llmfit desktop application acts as a thin Tauri wrapper that exposes llmfit-core functionality through serializable commands, allowing the JavaScript UI to invoke Rust methods for hardware detection, model fitting, and provider operations.

The AlexsJones/llmfit repository implements a machine learning model fitting tool with a native desktop interface. The llmfit Tauri desktop application integrates with the core Rust library through a command-based architecture that keeps hardware detection, model catalog management, and inference provider logic decoupled from the presentation layer.

Command Registration in the Tauri Layer

The integration begins in llmfit-desktop/src/main.rs, where the Tauri builder registers Rust functions as invokable commands. These commands serve as the exclusive bridge between the web-based UI and the system-level capabilities of the core library.

Exposing Core APIs as Tauri Commands

The desktop application defines several #[tauri::command] functions that act as thin shims over llmfit-core APIs:

  • get_system_specs – Wraps SystemSpecs::detect() from llmfit-core/src/hardware.rs to gather RAM, CPU, and GPU information
  • get_model_fits – Invokes ModelDatabase::new() from llmfit-core/src/models.rs and ModelFit::analyze() from llmfit-core/src/fit.rs to evaluate models against detected hardware
  • start_pull and poll_pull – Interface with the OllamaProvider for model download management
  • is_ollama_available – Checks provider connectivity

Each command returns results serialized through #[derive(Serialize)] structs, enabling automatic marshalling to the JavaScript side without custom deserialization logic.

#[tauri::command]
fn get_system_specs() -> Result<SystemInfo, String> {
    let specs = SystemSpecs::detect();
    let gpus = specs.gpus.iter().map(|g| GpuInfoJs {
        name: g.name.clone(),
        vram_gb: g.vram_gb,
        backend: format!("{:?}", g.backend),
        count: g.count,
        unified_memory: g.unified_memory,
    }).collect();

    Ok(SystemInfo {
        total_ram_gb: specs.total_ram_gb,
        available_ram_gb: specs.available_ram_gb,
        cpu_name: specs.cpu_name.clone(),
        cpu_cores: specs.total_cpu_cores,
        gpus,
        unified_memory: specs.unified_memory,
    })
}

Managing Shared State Across the Rust-JavaScript Boundary

The integration uses Tauri's state management to maintain persistent connections across command invocations. An AppState struct holds a singleton OllamaProvider (from llmfit-core/src/providers.rs) and a mutex-protected optional pull handle.

This state is injected into commands via State<'_, AppState>, allowing the UI to start long-running model downloads and monitor progress without recreating provider objects or losing connection context between calls.

The JavaScript Bridge and UI Integration

The front-end code in llmfit-desktop/ui/app.js consumes the registered commands through Tauri's invoke API. The JavaScript layer remains purely presentational, delegating all computational work to the Rust core.

import { invoke } from '@tauri-apps/api/tauri';

async function loadSystemInfo() {
  const info = await invoke('get_system_specs');
  document.getElementById('cpu').textContent = `${info.cpu_name} (${info.cpu_cores} cores)`;
  document.getElementById('ram').textContent = `${info.total_ram_gb.toFixed(1)} GB total`;
  // Render GPU list …
}
loadSystemInfo();

When fetching model fits, the JavaScript invokes the Rust command and renders the returned JSON array:

async function loadModelFits() {
  const fits = await invoke('get_model_fits');
  const tbody = document.querySelector('#model-table tbody');
  tbody.innerHTML = '';
  fits.forEach(fit => {
    const row = document.createElement('tr');
    row.innerHTML = `
      <td>${fit.name}</td>
      <td>${fit.params_b.toFixed(2)} B</td>
      <td>${fit.quant}</td>
      <td>${fit.fit_level}</td>
      <td>${fit.run_mode}</td>
      <td>${fit.score.toFixed(2)}</td>
    `;
    tbody.appendChild(row);
  });
}
loadModelFits();

The corresponding Rust command handles the complex analysis logic:

#[tauri::command]
fn get_model_fits() -> Result<Vec<ModelFitInfo>, String> {
    let specs = SystemSpecs::detect();
    let db = ModelDatabase::new();

    let fits = db.get_all_models()
        .iter()
        .map(|m| ModelFit::analyze(m, &specs))
        .collect::<Vec<_>>();

    let ranked = llmfit_core::fit::rank_models_by_fit(fits);

    Ok(ranked.into_iter().map(|f| ModelFitInfo {
        name: f.model.name.clone(),
        params_b: f.model.parameters_raw.unwrap_or(0) as f64 / 1e9,
        quant: f.best_quant.clone(),
        fit_level: match f.fit_level {
            FitLevel::Perfect => "Perfect",
            FitLevel::Good => "Good",
            FitLevel::Marginal => "Marginal",
            FitLevel::TooTight => "Too Tight",
        }.to_string(),
        run_mode: match f.run_mode {
            RunMode::Gpu => "GPU",
            RunMode::CpuOffload => "CPU Offload",
            RunMode::CpuOnly => "CPU Only",
            RunMode::MoeOffload => "MoE Offload",
            RunMode::TensorParallel => "Tensor Parallel",
        }.to_string(),
        score: f.score,
        memory_required_gb: f.memory_required_gb,
        memory_available_gb: f.memory_available_gb,
        utilization_pct: f.utilization_pct,
        estimated_tps: f.estimated_tps,
        use_case: format!("{:?}", f.use_case),
        runtime: match f.runtime {
            InferenceRuntime::LlamaCpp => "llama.cpp",
            InferenceRuntime::Mlx => "MLX",
            InferenceRuntime::Vllm => "vLLM",
            InferenceRuntime::Unsupported => "unsupported",
        }.to_string(),
        installed: f.installed,
        notes: f.notes.clone(),
        release_date: f.model.release_date.clone(),
    }).collect())
}

Architectural Separation of Concerns

The integration maintains strict boundaries between the Tauri-specific desktop code and the reusable core library. All domain logic—including hardware detection in llmfit-core/src/hardware.rs, model catalog management in llmfit-core/src/models.rs, and fit analysis in llmfit-core/src/fit.rs—resides in llmfit-core.

The desktop crate handles only three responsibilities: registering Tauri commands, managing stateful provider connections, and packaging static assets (index.html, styles.css). This separation ensures the core library remains usable by the CLI (llmfit-tui) and Python wrapper without pulling in Tauri dependencies or web runtime overhead.

Summary

  • Command-based integration – llmfit-desktop/src/main.rs registers thin command wrappers that delegate to llmfit-core APIs like SystemSpecs::detect() and ModelFit::analyze()
  • Automatic serialization – Rust structs derive Serialize to enable seamless data transfer across the JavaScript boundary without custom marshalling code
  • Stateful persistence – The AppState struct maintains OllamaProvider instances across invocations using Tauri's dependency injection system
  • Clean architecture – All heavy logic stays in llmfit-core, making the library reusable by CLI and Python consumers while the desktop layer focuses strictly on UI concerns

Frequently Asked Questions

How does the Tauri front-end call functions in the Rust core library?

The front-end uses Tauri's invoke API to call commands registered in llmfit-desktop/src/main.rs. Each command is a Rust function marked with #[tauri::command] that internally calls methods from llmfit-core, such as SystemSpecs::detect() or ModelDatabase::new(), and returns serializable structs that Tauri automatically converts to JavaScript objects.

Where is the application state stored in the llmfit desktop app?

Application state is stored in an AppState struct managed by Tauri's state system. This struct, defined in the desktop crate, holds a singleton OllamaProvider from llmfit-core/src/providers.rs and a mutex-protected pull handle. Tauri injects this state into command handlers via State<'_, AppState>, allowing persistent connections across multiple UI interactions.

Can the core library be used without the Tauri desktop interface?

Yes. The llmfit-core crate contains no Tauri dependencies and exposes a standard Rust API used by both the desktop application and the llmfit-tui CLI tool. Hardware detection, model fitting, and provider interactions all live in llmfit-core, making the library consumable by any Rust binary, Python wrapper, or alternative interface without the overhead of the webview runtime.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →