Case study / 06 / Native Android pantry app
ShelfLife
A native Android app for households that combines local pantry inventory, expiration tracking, barcode and receipt scanning, shopping lists, and AI-assisted recipe ideas.

ShelfLife / Interface overview
01 / Context
The problem to solve.
Household ingredients are easy to forget after purchase, which makes expiration dates, duplicate buying, and meal planning difficult to manage.
02 / Approach
From need to interface.
ShelfLife keeps a local pantry inventory, surfaces expiry information, and reduces manual entry through barcode and receipt scanning with optional recipe assistance.
What I built
- Native Compose interface
- Local pantry and expiry tracking
- Barcode and receipt scanning
- AI-assisted recipe ideas

03 / Implementation
How it fits together.
A Kotlin and Jetpack Compose Android client uses Room for local inventory persistence. ML Kit supports barcode and receipt scanning, Firebase provides cloud services and security rules, and a Cloudflare Worker proxies AI requests so provider credentials are not embedded in the app.
Decisions that shaped the build
- Used Room as the local source for essential pantry data
- Kept scan results reviewable before saving
- Routed AI requests through a Worker instead of calling the provider directly from Android
Challenges
- Keeping core pantry data useful without a network connection
- Turning imperfect barcode and receipt input into editable inventory records
- Calling AI features without shipping private service credentials in the APK
04 / Delivery & lessons
Built, tested, and still learning.
Testing
Kotlin unit tests cover pantry-item saving and DAO isolation, Firebase emulator tests validate Firestore rules, and Node tests cover Worker validation. An Android instrumentation test scaffold is present. Run `gradlew test`, `npm test` in `firebase-tests`, and `npm test` in `worker`; broader Compose UI, scanner-device, and end-to-end tests remain to be added.
Deployment
No public store release or downloadable build is linked.
What I took forward
- Local-first storage keeps everyday utilities resilient
- Scanner results need correction paths because recognition is imperfect
- Mobile secrets belong behind a server-side proxy