<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Samarth Nagpal</title>
    <description>The latest articles on DEV Community by Samarth Nagpal (@samarth_nagpal_7c1ba5f72b).</description>
    <link>https://dev.to/samarth_nagpal_7c1ba5f72b</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3726525%2F5c0aa1e1-7045-4ac2-a9f1-385749519747.png</url>
      <title>DEV Community: Samarth Nagpal</title>
      <link>https://dev.to/samarth_nagpal_7c1ba5f72b</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/samarth_nagpal_7c1ba5f72b"/>
    <language>en</language>
    <item>
      <title>I Built SplitEase: An Unlimited Expense Splitting App Without Paywalls (Splitwise Alternative)</title>
      <dc:creator>Samarth Nagpal</dc:creator>
      <pubDate>Thu, 22 Jan 2026 15:58:10 +0000</pubDate>
      <link>https://dev.to/samarth_nagpal_7c1ba5f72b/i-built-splitease-an-unlimited-expense-splitting-app-without-paywalls-splitwise-alternative-43a9</link>
      <guid>https://dev.to/samarth_nagpal_7c1ba5f72b/i-built-splitease-an-unlimited-expense-splitting-app-without-paywalls-splitwise-alternative-43a9</guid>
      <description>&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;During a weekend trip with roommates, we hit Splitwise's &lt;strong&gt;3 expenses per day limit by noon&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Breakfast, gas station stop, and hotel check-in used up our quota. We had to either &lt;strong&gt;wait until midnight&lt;/strong&gt; to log lunch and dinner or &lt;strong&gt;pay for premium just to track our own spending&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That felt ridiculous for such a basic feature — so &lt;strong&gt;SplitEase&lt;/strong&gt; was built to solve exactly this problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is SplitEase?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;SplitEase&lt;/strong&gt; is a completely free, no-limits expense splitting app for students, flatmates, and travel groups.&lt;/p&gt;

&lt;p&gt;Think &lt;strong&gt;Splitwise — but without artificial restrictions.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Live App: &lt;a href="https://www.split-ease.app/" rel="noopener noreferrer"&gt;https://www.split-ease.app/&lt;/a&gt;&lt;br&gt;
Product Hunt: &lt;a href="https://producthunt.com/posts/splitease-2" rel="noopener noreferrer"&gt;https://producthunt.com/posts/splitease-2&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Unlimited expenses per day — no artificial restrictions&lt;/li&gt;
&lt;li&gt;Unlimited groups — track as many friend circles as needed&lt;/li&gt;
&lt;li&gt;Real-time sync across all devices using WebSockets&lt;/li&gt;
&lt;li&gt;Push notifications for payment reminders&lt;/li&gt;
&lt;li&gt;Smart debt simplification algorithm&lt;/li&gt;
&lt;li&gt;Edit and delete expenses anytime — included free&lt;/li&gt;
&lt;li&gt;PWA support with offline capabilities&lt;/li&gt;
&lt;li&gt;Clean, modern interface&lt;/li&gt;
&lt;li&gt;Completely free forever — no ads, no premium tier&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Frontend
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;React with Zustand for state management&lt;/li&gt;
&lt;li&gt;React Router for navigation&lt;/li&gt;
&lt;li&gt;Framer Motion for animations&lt;/li&gt;
&lt;li&gt;Socket.io-client for real-time updates&lt;/li&gt;
&lt;li&gt;PWA with service workers and push notifications&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Backend
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Node.js + Express.js RESTful API&lt;/li&gt;
&lt;li&gt;MongoDB with Mongoose ODM&lt;/li&gt;
&lt;li&gt;Socket.io for WebSocket connections&lt;/li&gt;
&lt;li&gt;JWT authentication&lt;/li&gt;
&lt;li&gt;Google OAuth 2.0 integration&lt;/li&gt;
&lt;li&gt;Brevo for email notifications&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Deployment
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Frontend: Vercel&lt;/li&gt;
&lt;li&gt;Backend: Railway&lt;/li&gt;
&lt;li&gt;Database: MongoDB Atlas&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Technical Challenges and Solutions
&lt;/h2&gt;


&lt;h3&gt;
  
  
  1. Real-time Debt Updates Across Multiple Devices
&lt;/h3&gt;

&lt;p&gt;When one person adds an expense, &lt;strong&gt;everyone in the group must instantly see updated balances&lt;/strong&gt; — without refreshing the page.&lt;/p&gt;

&lt;p&gt;This became tricky because:&lt;/p&gt;
&lt;h4&gt;
  
  
  What Was Going Wrong
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Multiple users could edit or add expenses at the same time&lt;/li&gt;
&lt;li&gt;Traditional REST polling caused delays and unnecessary server load&lt;/li&gt;
&lt;li&gt;Sending updates to all connected users wasted bandwidth&lt;/li&gt;
&lt;li&gt;Race conditions caused outdated balances to briefly appear&lt;/li&gt;
&lt;/ul&gt;


&lt;h4&gt;
  
  
  How It Was Fixed
&lt;/h4&gt;
&lt;h5&gt;
  
  
  Group-based WebSocket Rooms
&lt;/h5&gt;

&lt;p&gt;Each group has its own dedicated Socket.io room.&lt;/p&gt;

&lt;p&gt;Only members of that group receive updates — keeping traffic efficient and isolated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Server-side&lt;/span&gt;
&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`group-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;groupId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;io&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`group-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;groupId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;expense-added&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newExpense&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h5&gt;
  
  
  Event-Driven State Updates
&lt;/h5&gt;

&lt;p&gt;Instead of refetching all expenses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Clients listen for events like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;expense-added&lt;/li&gt;
&lt;li&gt;expense-updated&lt;/li&gt;
&lt;li&gt;expense-deleted&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Zustand store updates only affected data&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;UI re-renders instantly&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;




&lt;h5&gt;
  
  
  Optimistic UI With Rollback
&lt;/h5&gt;

&lt;p&gt;To keep the app feeling fast:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UI updates immediately when a user adds an expense&lt;/li&gt;
&lt;li&gt;Backend confirmation follows&lt;/li&gt;
&lt;li&gt;If a request fails, the UI automatically rolls back&lt;/li&gt;
&lt;/ul&gt;




&lt;h5&gt;
  
  
  Connection Recovery Handling
&lt;/h5&gt;

&lt;p&gt;Socket reconnection was added to handle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;App backgrounding&lt;/li&gt;
&lt;li&gt;Network drops&lt;/li&gt;
&lt;li&gt;Device sleep&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On reconnect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Client re-joins all group rooms&lt;/li&gt;
&lt;li&gt;Syncs latest balances&lt;/li&gt;
&lt;li&gt;Prevents stale state bugs&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  Result
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Sub-second balance updates&lt;/li&gt;
&lt;li&gt;No page refresh required&lt;/li&gt;
&lt;li&gt;Works smoothly across multiple devices&lt;/li&gt;
&lt;li&gt;Reduced server load compared to polling&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  2. Debt Simplification Without Weird Rounding Bugs
&lt;/h3&gt;

&lt;p&gt;The first version of the “who owes whom” logic worked on floats.&lt;/p&gt;

&lt;p&gt;That caused results like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;₹249.999999&lt;/li&gt;
&lt;li&gt;Off-by-₹1 mismatches&lt;/li&gt;
&lt;li&gt;Totals not summing to zero&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  What Was Going Wrong
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Floating-point math caused precision errors&lt;/li&gt;
&lt;li&gt;Errors accumulated across many expenses&lt;/li&gt;
&lt;li&gt;Final debt graph didn’t balance mathematically&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  How It Was Fixed
&lt;/h4&gt;

&lt;h5&gt;
  
  
  Store Money as Integers
&lt;/h5&gt;

&lt;p&gt;All values are stored in &lt;strong&gt;paise instead of rupees&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;₹250.50 → stored as &lt;code&gt;25050&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h5&gt;
  
  
  Integer-Only Simplification Algorithm
&lt;/h5&gt;

&lt;p&gt;The entire simplification logic runs on integers.&lt;/p&gt;

&lt;p&gt;Conversion back to rupees happens only at display time.&lt;/p&gt;




&lt;h5&gt;
  
  
  Added Sanity Checks
&lt;/h5&gt;

&lt;p&gt;Automated tests verify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sum of balances always equals zero&lt;/li&gt;
&lt;li&gt;No fractional remainders&lt;/li&gt;
&lt;li&gt;No negative rounding artifacts&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  Result
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Perfectly balanced settlements&lt;/li&gt;
&lt;li&gt;No decimal glitches&lt;/li&gt;
&lt;li&gt;Accurate large-group calculations&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  3. Web Push Notifications That Actually Deliver
&lt;/h3&gt;

&lt;p&gt;Web push notifications were far harder than just installing a library.&lt;/p&gt;




&lt;h4&gt;
  
  
  What Was Going Wrong
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Users granted permission but never received notifications&lt;/li&gt;
&lt;li&gt;Invalid subscriptions accumulated&lt;/li&gt;
&lt;li&gt;Old service workers remained active&lt;/li&gt;
&lt;li&gt;Silent failures&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  How It Was Fixed
&lt;/h4&gt;

&lt;h5&gt;
  
  
  Subscription Validation Endpoint
&lt;/h5&gt;

&lt;p&gt;Each subscription is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verified before saving&lt;/li&gt;
&lt;li&gt;Validated for required fields&lt;/li&gt;
&lt;li&gt;Rejected if malformed&lt;/li&gt;
&lt;/ul&gt;




&lt;h5&gt;
  
  
  Automatic Cleanup
&lt;/h5&gt;

&lt;p&gt;When push sending fails:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Subscription is deleted automatically&lt;/li&gt;
&lt;li&gt;Prevents repeated failures&lt;/li&gt;
&lt;li&gt;Keeps database clean&lt;/li&gt;
&lt;/ul&gt;




&lt;h5&gt;
  
  
  Versioned Service Worker Strategy
&lt;/h5&gt;

&lt;p&gt;Service workers are versioned.&lt;/p&gt;

&lt;p&gt;When a new version is detected:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Old worker is invalidated&lt;/li&gt;
&lt;li&gt;Client re-registers&lt;/li&gt;
&lt;li&gt;Everyone converges to latest logic&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  Result
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Reliable cross-browser delivery&lt;/li&gt;
&lt;li&gt;Consistent mobile notifications&lt;/li&gt;
&lt;li&gt;Clean subscription database&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Architecture Highlights
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Modular API structure (routes, controllers, services)&lt;/li&gt;
&lt;li&gt;JWT authentication middleware&lt;/li&gt;
&lt;li&gt;Centralized error handling&lt;/li&gt;
&lt;li&gt;MongoDB indexing on &lt;code&gt;userId&lt;/code&gt; and &lt;code&gt;groupId&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Input validation using express-validator&lt;/li&gt;
&lt;li&gt;Secure CORS configuration&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;Based on Product Hunt feedback:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multi-currency support&lt;/li&gt;
&lt;li&gt;Trip-based expense summaries&lt;/li&gt;
&lt;li&gt;Export to PDF and Excel&lt;/li&gt;
&lt;li&gt;WhatsApp and SMS notifications&lt;/li&gt;
&lt;li&gt;Expense categories and analytics&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Try It Out
&lt;/h2&gt;

&lt;p&gt;SplitEase is built for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Students&lt;/li&gt;
&lt;li&gt;Flatmates&lt;/li&gt;
&lt;li&gt;Travel groups&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No limits. No paywalls. No ads.&lt;/p&gt;

&lt;p&gt;Live App: &lt;a href="https://www.split-ease.app/" rel="noopener noreferrer"&gt;https://www.split-ease.app/&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Real-time sync requires careful race-condition handling&lt;/li&gt;
&lt;li&gt;OAuth and email auth need heavy testing&lt;/li&gt;
&lt;li&gt;PWAs require proper service worker lifecycle management&lt;/li&gt;
&lt;li&gt;User feedback directly shapes roadmap&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Built with React, Node.js, MongoDB, and many late nights.&lt;/p&gt;

&lt;p&gt;Launching on Product Hunt today — would love your feedback.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>react</category>
      <category>startup</category>
    </item>
  </channel>
</rss>
