After months of late-night coding, debugging, and wrestling with compiler errors, I finally reached a major milestone: I published my first-ever desktop application to the Microsoft Store. π
The app is called Focus Stream. It tracks how you spend time on your PC and turns it into an AI-generated focus journal. The catch? It runs fully on-device. No accounts, no cloud database, and absolutely no telemetry. Window snapshots, activity timelines, and LLM inference all happen locally.
In this post, I want to share the architecture behind Focus Stream, how I fit a local Large Language Model (LLM) into a lightweight desktop app, and what it took to package and ship it to the Microsoft Store.
The Core Concept: Privacy-First AI
We've all seen the news about cloud-based activity trackers scanning user screens. While productivity tracking is incredibly useful, uploading your screen snapshots, open documents, and active window titles to a third-party server feels like a major privacy risk.
I wanted to build a tool that gives you the power of AI analysis and natural language query over your day, but with zero data leaving your machine.
To make this happen, I designed a local-first architecture:
[ User Desktop ]
β
βΌ (Activity logs & snapshots sampled)
[ Local SQLite Database ]
β
βββββββββββββββββββββββββββββββββ
βΌ βΌ
[ React 19 Frontend ] βββββββββ [ Local Llama 3.2 1B ]
(Visual timeline, trends) (Local inference via mistral.rs)
The Tech Stack
I chose a stack that balances web-ecosystem UI flexibility with native-performance system hooks:
| Layer | Technology |
|---|---|
| Frontend | React 19, TypeScript, Vite, Recharts, Base UI |
| Backend | Rust, Tauri 2 |
| Database | SQLite (tauri-plugin-sql with WAL enabled) |
| AI Inference |
mistral.rs running a quantized Llama 3.2 1B model |
| Packaging | MSIX (x64 and arm64), Microsoft Store |
Deep Dive: Solving the Local LLM Challenge
Running a local LLM inside a desktop application introduces two major hurdles:
- How do you keep the installer small? You can't bundle a 1.2 GB GGUF model in the installer without turning away users.
- How do you support multiple architectures and hardware setups (CPU vs. GPU)?
Here is how I solved them.
1. The Dynamic DLL & On-Demand Model Download
Instead of compiling the AI inference engine directly into the main binary, I built a modular architecture using compile-time features.
Focus Stream compiles in production with an ai_dll feature flag. The core executable is extremely slim.
- First Launch: The app prompts the user to download the Llama 3.2 1B model (~1.2 GB quantized GGUF) directly from Hugging Face into their local app data directory.
-
Dynamic Linking: At runtime, the app checks the system architecture and dynamically loads the compiled C-compatible DLL (
focus_stream_cpu.dllor a future GPU-accelerated equivalent) using thelibloadingcrate in Rust.
// A look at how we dynamically load the inference backend at runtime
pub fn load_backend(path: &Path) -> Result<Box<dyn AIBackend>, Box<dyn Error>> {
unsafe {
let lib = libloading::Library::new(path)?;
let constructor: libloading::Symbol<unsafe extern "C" fn() -> *mut dyn AIBackend> =
lib.get(b"create_backend")?;
Ok(Box::from_raw(constructor()))
}
}
This keeps the base application installer under 70MB, downloading the heavy LLM weights only when the user is ready.
2. Multi-Architecture CPU Builds (x64 + arm64)
Since Windows runs on both Intel/AMD (x64) and Snapdragon (arm64) architectures, Focus Stream had to support both.
I wrote a PowerShell script that compiles the CPU DLLs targeting both architectures:
# Building the Rust-based CPU backend DLL for ARM64
pwsh src-tauri/scripts/build-cpu-backend.ps1 aarch64-pc-windows-msvc
In our CI/CD pipeline, both the x86_64-pc-windows-msvc and aarch64-pc-windows-msvc DLLs are bundled as resources, ensuring native execution speeds regardless of the processor.
Wrestling with the Microsoft Store & MSIX Packaging
This was my first time packaging a desktop app for the Microsoft Store, and the learning curve was steep. The store requires signing your app package inside a .msix container.
Version Synchronization
To release updates, the Microsoft Store requires a 4-part version structure (e.g., 1.0.0.0) in your XML app manifest, while npm uses SemVer (e.g., 1.0.0).
To avoid manual mistakes, I wrote a Node script (sync-version.mjs) that acts as a single source of truth. When I run pnpm version, the script automatically:
- Bumps
package.json - Syncs the version to Tauri's config files (
tauri.conf.json) - Syncs the cargo version in
Cargo.toml - Propagates the version to the XML elements in
Package.Store.appxmanifest
CI/CD Automation
Our GitHub Actions pipeline builds both x64 and arm64 MSIX installers, merges them into a single .msixbundle file, and uses the Windows Partner Center API to submit the build directly to the Microsoft Store when a tag is pushed.
Lessons Learned on My First Desktop Launch
- Rust is a perfect match for Tauri 2: Writing low-level native logic (like screen capturing, active window polling, and database caching) in Rust is extremely safe and fast, while React lets me build a modern dashboard with ease.
- Local AI is highly viable: You don't need a RTX 4090 to run local inference. Llama 3.2 1B runs surprisingly fast on mid-range laptop CPUs using quantization. It's more than capable of summarizing text journals and doing lightweight RAG.
- Packaging is 50% of the battle: Building the app is only half the job. Code signing, target architectures, MSIX manifest constraints, and store policy reviews take a significant amount of effort.
What's Next?
Now that the foundation is live on the store, I am working on:
- Optional GPU Acceleration: Packaging CUDA-compatible DLLs that automatically load if a user has a dedicated NVIDIA GPU, falling back to CPU if not.
-
More detailed dashboards: Using
rechartsto build granular charts tracking productivity trends over months.
Focus Stream is available on the Microsoft Store with a 7-day free trial and a one-time purchase of $9.99 (no subscriptions!). If you are a developer, freelancer, or someone looking to analyze your time privately, I'd love for you to check it out.
Have you built desktop apps with Tauri 2? Have you experimented with local LLM integration on client machines? Let's discuss in the comments below!

Top comments (0)