Our own project · Case study

LithoCanvas Case Study A collector app from idea to backend

LithoCanvas is our own Android app for mineral and art collections. This case study shows how we built it: app architecture, backend, billing and privacy, planned the same way we plan client projects.

  • React Native 0.88
  • React 19
  • Expo SDK 58
  • Cloudflare Workers
2 Languages German and English from the first build
EU Data location D1 database and private R2 storage in the EU
0 Provider keys in the app Image recognition runs through our own server
3 Subscription tiers Bought through Google Play, status verified server side

The app

Four screens

LithoCanvas home screen with a button to identify minerals and art and a preview of the collection.
Scan screen asking what you discovered, with tips for even lighting.
Saved pyrite with photo, hardness, crystal system and identification confidence.
Mineral collection with photos of rose quartz and wulfenite, search and filters.

What we built

The app keeps collections, identifies photos on request and syncs everything with a backend of our own. Four decisions shape the architecture.

  • The collection lives on the device first

    Records, photos and notes sit in a local SQLite database per account. Changes wait in a durable queue until they sync, so nothing is lost offline.

  • Identification through our own server

    A photo leaves the device only after consent. A worker checks the request, counts quotas and calls the recognition provider. The provider key never ships in the app package.

  • Billing with server verification

    Purchases go through Google Play. The backend verifies each purchase and decides which plan applies.

  • Account, export and deletion

    Registration, password recovery by email, data export and account deletion were part of the scope from day one.

Tech stack

in detail

  • React Native 0.88

    Bare React Native with React 19 and TypeScript 6. Android builds run locally through Gradle, without a cloud build service.

    Framework
  • Expo SDK 58 modules

    Camera, image picker, file system and notifications come in as individual modules.

    Native modules
  • expo-sqlite + Zustand

    An account-bound database on the device, plus a queue for pending changes and deletions.

    Local data
  • Cloudflare Workers

    Sign-in, access checks, identification proxy, quotas, purchase verification, media, export and account deletion.

    Backend
  • D1 + R2

    Versioned D1 migrations for the schema and private R2 buckets for photos, both in the EU.

    Data
  • react-native-iap

    Google Play purchases in the app, verification and plan status in the worker.

    Billing
  • Cloudflare Email Service

    Recovery emails go out through the worker's send_email binding.

    Email

Decisions that also matter in client projects

Migration

The backend moved from Supabase to Cloudflare Workers, D1 and R2. We verified the migration and then switched off the old resources.

Honest results

The app keeps your own observations apart from machine estimates. It does not invent confidence, provenance or value for a piece.

Clear subscription rules

Recurring costs, scan limits and what remains after cancellation are stated in the app. There is no trial that charges you later.