Back to Portfolio

BillFlow: Technical Deep Dive

How I built an offline-first invoicing platform from scratch

View Live Product

The Problem I Solved

User Pain Point:

Indian SMB owners (like my friend Tameem, a furniture shop owner) were trapped between two bad options: 1. Pen & paper - Fast but error-prone, no records 2. Excel - Professional but slow, requires internet, frustrating UX

The Market Gap:

No existing tool was BOTH offline-first AND mobile-native. Every "invoicing app" assumed stable internet—a luxury most small shops don't have.

My Insight:

Build for the worst-case scenario (zero internet) and everything else becomes easier.

Technical Challenges & Solutions

Challenge 1: Offline-First Data Architecture

"Firebase is cloud-first. How do you build a reliable offline experience when the database expects internet?"

  • Implemented Firebase's offline persistence layer
  • Built custom conflict resolution for simultaneous edits from multiple devices
  • Used Firestore's atomic transactions for stock updates (critical for inventory accuracy)

Code Decision:

I chose Firestore over a traditional SQL database because:

  • Built-in real-time sync (no custom WebSocket code)
  • Offline persistence out-of-the-box
  • Simpler security rules for user data isolation

Trade-off:

This meant accepting eventual consistency instead of strict ACID guarantees—acceptable for SMB invoicing but would be wrong for, say, banking.

Challenge 2: Mobile-First UX with Complex Features

"Invoicing requires complex workflows (customer selection, item search, calculations, PDF generation) but must feel instant on a mobile device."

  • Built the "Unified Invoice Hub" - a dual-view interface (All Invoices vs. By Customer)
  • Implemented virtual scrolling for large customer lists
  • Used React Context to avoid prop-drilling in deeply nested components
  • Lazy-loaded PDF generation (only renders when user clicks "Download")

Performance Result:

  • Initial page load: <2 seconds on 3G
  • Invoice creation: <10 seconds end-to-end
  • Offline invoice save: Instant (localStorage buffer)

Challenge 3: Payment UX for Low-Tech Users

"UPI is ubiquitous in India, but getting customers to scan QR codes required making it brain-dead simple."

  • Auto-generate UPI QR codes from business details
  • Created a shareable QR image (PNG) with logo and invoice details
  • Integrated native device share API for WhatsApp/SMS distribution

Why This Matters:

Shop owners don't email invoices in India—they WhatsApp them. I built for the actual behavior, not the "ideal" workflow.

System Architecture

Tech Stack Decisions:

Frontend:

Next.js (App Router) - For PWA support and optimal performance TypeScript - Type safety across 50+ components Tailwind + ShadCN UI - Rapid, consistent design system

Backend:

Firebase Auth - Secure user management Firestore - Real-time database with offline support Cloud Storage - Invoice PDF archival

Data Model:

Every document (invoices, products, customers) includes a userId field. This is critical: - Ensures data isolation (User A can't see User B's invoices) - Simplifies security rules (no complex nested queries) - Allows for walk-in invoices (not tied to a customer but still owned by the business)

Security Approach:

All Firestore rules are userId-based. Even if a bug exposes a document ID, cross-user data leaks are impossible.

Deployment & Performance

Hosting:

Firebase App Hosting (auto-deploys from GitHub) PWA manifest for "Add to Home Screen" functionality

Performance Metrics:

Lighthouse Score: 98/100 (Performance) First Contentful Paint: <1.5s Time to Interactive: <2.5s

Real-World Usage:

Tested with 5 beta users (shop owners) Handles invoices up to 50 line items without lag Offline invoice creation works even with complete network loss

What I Learned

Technical Lessons:

  • Offline-first is a design philosophy, not a feature. Every decision (data structure, UX flow, error handling) must assume zero connectivity.
  • Firebase is incredible for solo builders. I shipped this in 3 weeks because I didn't have to build auth, database, or hosting from scratch.
  • AI-accelerated development is real. I used Claude/Cursor for boilerplate, debugging, and architecture validation—but I reviewed every line. The LLM suggests, I decide.

Product Lessons:

  • Build for the worst-case user. My target user has a $100 Android phone and unreliable 3G. If it works for them, it works for everyone.
  • Speed trumps features. I cut 10+ "nice-to-have" features from V1 to ship faster. Users don't care about what's missing—they care about what works.
  • Metrics matter from Day 1. I built analytics hooks before launch so I could see: Where do users drop off? What features get used?

Bonus: AI Twin - A RAG Implementation

While building my portfolio, I realized: "Why make recruiters read a PDF resume when they can just ask questions?"

The Build:

  • Built a custom RAG (Retrieval-Augmented Generation) chatbot using Gemini 2.0 Flash
  • Trained it on all my project docs (BillFlow, DukaanBill, NoteVault), resume, and methodologies
  • Custom chat UI with suggested prompts and error handling

Technical Stack:

  • Gemini 2.0 Flash API (for speed + cost efficiency)
  • Vector embeddings for context retrieval
  • Next.js API routes for backend
  • Responsive modal interface

Why This Matters:

This isn't a resume gimmick—it's a demonstration of practical AI implementation. I can architect, build, and deploy AI features that solve real UX problems.

Try it: Click the ✨ icon on my portfolio to chat with my AI twin.