BillFlow: Technical Deep Dive
How I built an offline-first invoicing platform from scratch
View Live ProductThe 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.