Skip to content
MobilePersonal project

Resiboo

Resiboo is an offline-first receipt scanner for iOS and Android: scan a receipt and it reads the merchant, date, category, and total, then files it — no account, no cloud required.

The Problem

People don't lack budgeting apps — they lack the patience to type merchant, date, and total into one, every day, forever. Resiboo deliberately isn't a personal-finance app: no budgeting, no bank connections, no financial advice. It targets the data-entry problem itself, not financial literacy.

My Role

Solo developer, end to end: product spec and design system, the on-device OCR/extraction pipeline, the local database schema, native iOS integrations, and the full app UI.

What I Built

  • Camera capture → OCR → review/confirm flow, plus manual entry and batch capture
  • A deterministic, rule-based extraction pipeline (merchant, date, category, total) that runs entirely on-device with zero setup
  • An optional second extraction pass for line items via on-device Apple Intelligence or a user-supplied API key — additive only, never overrides or blocks the deterministic result
  • Merchant memory (alias resolution, learned category defaults), full-text receipt search, a stats view, and a freeform CSV export builder
  • Local backup/restore to iCloud or Google Drive, on-device reminders with recurring-merchant detection, and a natural-language 'Ask' chat over the user's own receipt data
  • Native iOS Shortcuts/App Intents (Swift) that turn a forwarded email or message into a saved receipt automatically

Architecture

  1. 1

    Expo / React Native

    The iOS & Android app

  2. 2

    Apple Vision / ML Kit OCR

    Reads the raw receipt text

  3. 3

    Deterministic scoring pipeline

    Rule-based merchant, date, total extraction

  4. 4

    Apple Intelligence / BYOK AI

    Optional, additive line-item pass

  5. 5

    expo-sqlite + Drizzle ORM

    The only datastore — no backend

Expo (SDK 57) with a custom tab implementation to fit a raised center action button, Uniwind (Tailwind v4), and React Native Reusables for the UI. The app is offline-first by construction, not by fallback: expo-sqlite plus Drizzle ORM is the only datastore — there's no backend and no server the app ever needs to reach. OCR runs through platform vision APIs (Apple Vision / ML Kit), with money stored as integer cents and dates as epoch millis to keep arithmetic and sorting exact.

Engineering Challenge

Receipts are inconsistent enough that a single OCR text block reliably produces false positives — card-authorization amounts that look like totals, discounted subtotals with no TOTAL label, split-tender receipts, and two receipts photographed side by side that merge into one block. Android and iOS also return OCR text in different shapes, so a scorer tuned on one platform silently degraded on the other. A separate native Visual Intelligence search integration hit an OS-level bug and had to be shelved.

Solution

Instead of an ML model, I built a deterministic, explainable scoring pipeline: named-signal confidence scoring, separator-agnostic amount parsing, and footer-boundary detection to separate a receipt's real total from a trailing card-auth line. Low-confidence or ambiguous results surface as a soft 'needs attention' flag rather than a hard failure or a silent wrong answer, and the optional AI pass is layered strictly on top of that — it can add line items but can never override or block what the deterministic pass already extracted.