Services AI Workflows Work Blog Hire Me
Case Study

Building jaklens.aiOffline AI Invoice Manager

Electron + Angular desktop app with local Qwen2.5 AI, SQLite, and llama.cpp. Built from zero to v1.0.0 in production — no cloud dependencies, no subscription.

Electron Angular .NET llama.cpp SQLite TypeScript
Platform
Windows desktop
AI Model
Qwen2.5 1.5B GGUF
Status
v1.0.0 live
The Problem

Manual invoice data entry is a silent tax on freelancers

Freelancers and small business owners waste 20–30 minutes per month manually typing invoice data into spreadsheets or accounting software. Over a year that adds up to half a day of lost time — every year.

Cloud-based alternatives like Dext or AutoEntry cost $30–200/month and store sensitive financial data on third-party servers. For privacy-conscious professionals and those in regulated industries, that's a non-starter.

20–30 min/month

Wasted on manual invoice data entry per freelancer

💸

$30–200/month

Cost of cloud OCR tools that also store your private data

🔒

Data privacy

Financial documents contain sensitive info — cloud storage is a risk

The Solution

A fully offline AI pipeline, right on your machine

The entire AI processing chain runs locally. Your data never leaves your computer.

Architecture

Shell
Electron
UI
Angular 17
Bridge
Node.js IPC
Inference
llama.cpp
Model
Qwen2.5 GGUF
Storage
SQLite
Engineering

Key technical challenges

1

Bundling a 1.5B GGUF model into an installer

Shipping a 418 MB GGUF model file inside an Electron installer required careful electron-builder configuration using extraResources. Path resolution between dev and production builds is handled via process.resourcesPath, avoiding the common trap of hardcoded paths.

2

Streaming token output through IPC

llama.cpp runs as a child_process.spawn with a readline interface reading stdout. Each token is forwarded to the Angular renderer via ipcMain events, producing a real-time streaming chat experience without any WebSocket infrastructure.

3

Reliable structured JSON from LLM output

LLMs are probabilistic — sometimes they ignore the format. The system prompt defines a strict JSON schema and the parsing layer uses regex extraction with a three-attempt retry loop. If all retries fail, the user sees a friendly degradation message rather than a crash.

Results

v1.0.0 shipped. Free download. Zero cloud dependencies.

100%
Offline — no internet required
$0
Cost to run — no API fees
418MB
Single installer with AI model

Have a project like this?

Desktop apps, local AI integration, offline-first architecture — let's talk about what you're building.

Let's talk