The Problem
During a weekend trip with roommates, we hit Splitwise's 3 expenses per day limit by noon.
Breakfast, gas station stop, and hotel check-in used up our quota. We had to either wait until midnight to log lunch and dinner or pay for premium just to track our own spending.
That felt ridiculous for such a basic feature — so SplitEase was built to solve exactly this problem.
What is SplitEase?
SplitEase is a completely free, no-limits expense splitting app for students, flatmates, and travel groups.
Think Splitwise — but without artificial restrictions.
Live App: https://www.split-ease.app/
Product Hunt: https://producthunt.com/posts/splitease-2
Key Features
- Unlimited expenses per day — no artificial restrictions
- Unlimited groups — track as many friend circles as needed
- Real-time sync across all devices using WebSockets
- Push notifications for payment reminders
- Smart debt simplification algorithm
- Edit and delete expenses anytime — included free
- PWA support with offline capabilities
- Clean, modern interface
- Completely free forever — no ads, no premium tier
Tech Stack
Frontend
- React with Zustand for state management
- React Router for navigation
- Framer Motion for animations
- Socket.io-client for real-time updates
- PWA with service workers and push notifications
Backend
- Node.js + Express.js RESTful API
- MongoDB with Mongoose ODM
- Socket.io for WebSocket connections
- JWT authentication
- Google OAuth 2.0 integration
- Brevo for email notifications
Deployment
- Frontend: Vercel
- Backend: Railway
- Database: MongoDB Atlas
Technical Challenges and Solutions
1. Real-time Debt Updates Across Multiple Devices
When one person adds an expense, everyone in the group must instantly see updated balances — without refreshing the page.
This became tricky because:
What Was Going Wrong
- Multiple users could edit or add expenses at the same time
- Traditional REST polling caused delays and unnecessary server load
- Sending updates to all connected users wasted bandwidth
- Race conditions caused outdated balances to briefly appear
How It Was Fixed
Group-based WebSocket Rooms
Each group has its own dedicated Socket.io room.
Only members of that group receive updates — keeping traffic efficient and isolated.
// Server-side
socket.join(`group-${groupId}`);
io.to(`group-${groupId}`).emit('expense-added', newExpense);
Event-Driven State Updates
Instead of refetching all expenses:
-
Clients listen for events like:
- expense-added
- expense-updated
- expense-deleted
Zustand store updates only affected data
UI re-renders instantly
Optimistic UI With Rollback
To keep the app feeling fast:
- UI updates immediately when a user adds an expense
- Backend confirmation follows
- If a request fails, the UI automatically rolls back
Connection Recovery Handling
Socket reconnection was added to handle:
- App backgrounding
- Network drops
- Device sleep
On reconnect:
- Client re-joins all group rooms
- Syncs latest balances
- Prevents stale state bugs
Result
- Sub-second balance updates
- No page refresh required
- Works smoothly across multiple devices
- Reduced server load compared to polling
2. Debt Simplification Without Weird Rounding Bugs
The first version of the “who owes whom” logic worked on floats.
That caused results like:
- ₹249.999999
- Off-by-₹1 mismatches
- Totals not summing to zero
What Was Going Wrong
- Floating-point math caused precision errors
- Errors accumulated across many expenses
- Final debt graph didn’t balance mathematically
How It Was Fixed
Store Money as Integers
All values are stored in paise instead of rupees.
Example:
- ₹250.50 → stored as
25050
Integer-Only Simplification Algorithm
The entire simplification logic runs on integers.
Conversion back to rupees happens only at display time.
Added Sanity Checks
Automated tests verify:
- Sum of balances always equals zero
- No fractional remainders
- No negative rounding artifacts
Result
- Perfectly balanced settlements
- No decimal glitches
- Accurate large-group calculations
3. Web Push Notifications That Actually Deliver
Web push notifications were far harder than just installing a library.
What Was Going Wrong
- Users granted permission but never received notifications
- Invalid subscriptions accumulated
- Old service workers remained active
- Silent failures
How It Was Fixed
Subscription Validation Endpoint
Each subscription is:
- Verified before saving
- Validated for required fields
- Rejected if malformed
Automatic Cleanup
When push sending fails:
- Subscription is deleted automatically
- Prevents repeated failures
- Keeps database clean
Versioned Service Worker Strategy
Service workers are versioned.
When a new version is detected:
- Old worker is invalidated
- Client re-registers
- Everyone converges to latest logic
Result
- Reliable cross-browser delivery
- Consistent mobile notifications
- Clean subscription database
Architecture Highlights
- Modular API structure (routes, controllers, services)
- JWT authentication middleware
- Centralized error handling
- MongoDB indexing on
userIdandgroupId - Input validation using express-validator
- Secure CORS configuration
What's Next?
Based on Product Hunt feedback:
- Multi-currency support
- Trip-based expense summaries
- Export to PDF and Excel
- WhatsApp and SMS notifications
- Expense categories and analytics
Try It Out
SplitEase is built for:
- Students
- Flatmates
- Travel groups
No limits. No paywalls. No ads.
Live App: https://www.split-ease.app/
Lessons Learned
- Real-time sync requires careful race-condition handling
- OAuth and email auth need heavy testing
- PWAs require proper service worker lifecycle management
- User feedback directly shapes roadmap
Built with React, Node.js, MongoDB, and many late nights.
Launching on Product Hunt today — would love your feedback.
Top comments (1)
Happy to answer any technical questions. Feedback is welcome!.