The smartest way to split expenses with friends.
An AI-powered full-stack expense splitting app — built with Next.js 15, Convex, Clerk, Inngest, Gemini AI, and Shadcn UI. Track shared expenses, split bills effortlessly, and settle up quickly. Never worry about who owes who again.
| Landing Page | Dashboard | Group Expenses |
|---|---|---|
| Smart split, zero confusion | Track balances at a glance | Manage group debts easily |
- Create groups for roommates, trips, or events
- Invite friends and manage members
- Keep all group expenses organized in one place
- AI-powered algorithm minimizes the number of transactions needed to settle up
- Gemini AI generates personalized spending insights per user
- Understand your financial patterns with intelligent summaries
- Track spending patterns across groups and individuals
- Visual breakdown of shared costs
- Historical expense timeline
- Inngest-powered CRON jobs send automated email reminders for pending debts
- Resend integration for reliable email delivery
- Reminder cadence handled fully server-side — no manual follow-ups
- Split equally among all members
- Split by percentage
- Split by exact custom amounts
- Powered by Convex — see new expenses and payments the moment friends add them
- No refresh needed, everything syncs live
- Secure sign-up and login via Clerk
- Custom login and sign-up pages
- User data synced to Convex database automatically
| Layer | Technology |
|---|---|
| Frontend | Next.js 15 (App Router), TypeScript, Tailwind CSS |
| UI Components | Shadcn UI |
| Backend / Database | Convex (real-time serverless DB) |
| Authentication | Clerk |
| AI | Google Gemini AI (spending insights) |
| Background Jobs | Inngest (CRON jobs, reminders) |
| Resend | |
| Deployment | Vercel |
Make sure you have these installed:
node --version # v18+ required (v20+ recommended)
npm --version # v9+git clone https://github.com/YOUR_USERNAME/spliter.git
cd spliternpm install- Go to https://clerk.com and create a free account
- Create a new application
- Copy your API keys from the Clerk dashboard
npx convex devThis will prompt you to log in and create a new Convex project. Copy the deployment URL shown.
- Go to https://www.inngest.com and create a free account
- Copy your Event Key and Signing Key from the dashboard
- Go to https://resend.com and create a free account
- Generate an API key
cp .env.example .env.localEdit .env.local:
# Clerk Authentication
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
# Convex
NEXT_PUBLIC_CONVEX_URL=https://your-project.convex.cloud
# Gemini AI
GEMINI_API_KEY=your-gemini-api-key
# Inngest
INNGEST_EVENT_KEY=your-inngest-event-key
INNGEST_SIGNING_KEY=your-inngest-signing-key
# Resend (Email)
RESEND_API_KEY=re_...npm run devOpen http://localhost:3000 🎉
In a separate terminal, keep Convex running:
npx convex devspliter/
├── app/
│ ├── (auth)/
│ │ ├── sign-in/ # Custom Clerk sign-in page
│ │ └── sign-up/ # Custom Clerk sign-up page
│ ├── (main)/
│ │ ├── dashboard/ # Main dashboard — balances overview
│ │ ├── contacts/ # 1-on-1 expense tracking
│ │ ├── groups/ # Group expense management
│ │ │ └── [groupId]/ # Individual group page
│ │ └── layout.tsx # Authenticated layout with header
│ ├── api/
│ │ └── inngest/ # Inngest CRON job handlers
│ ├── globals.css
│ └── layout.tsx # Root layout
├── components/
│ ├── ui/ # Shadcn UI components
│ ├── header.tsx # App header with nav
│ ├── expense-form.tsx # Create/edit expense UI
│ └── settlement-form.tsx # Log payment UI
├── convex/
│ ├── schema.ts # Convex database schema
│ ├── users.ts # User mutations & queries
│ ├── groups.ts # Group mutations & queries
│ ├── expenses.ts # Expense mutations & queries
│ └── settlements.ts # Settlement mutations & queries
├── inngest/
│ ├── client.ts # Inngest client setup
│ ├── payment-reminders.ts # Automated reminder CRON
│ └── ai-insights.ts # Gemini AI insights CRON
├── lib/
│ └── utils.ts # Shared utilities
├── public/
│ ├── hero.png
│ └── logos/
├── .env.example
├── next.config.ts
├── tailwind.config.ts
└── tsconfig.json
Splitr uses Google Gemini AI for generating personalized spending insights per user. This runs as a background job via Inngest — not on every request — keeping it fast and cost-efficient.
Inngest CRON (weekly) → Fetch user's expense history from Convex
→ Send to Gemini AI with context prompt
→ Store AI insights back in Convex
→ Display on user dashboard
- Cost-effective for periodic, batch insight generation
- Natural language summaries of spending patterns (e.g. "You spent 40% more on dining this month")
- No sensitive financial data leaves the app — only aggregated totals are sent
Splitr uses Inngest for two automated CRON jobs:
| Job | Schedule | What it does |
|---|---|---|
| Payment Reminders | Daily | Finds unsettled debts and emails reminders via Resend |
| AI Insights | Weekly | Generates Gemini AI spending summaries per user |
These run fully server-side with zero manual intervention. No cron infrastructure to manage — Inngest handles retries, logs, and monitoring.
- Push code to GitHub
- Go to vercel.com → New Project → Import from GitHub
- Add all environment variables from
.env.local - Deploy — done! 🎉
For Inngest, register your production endpoint:
https://your-app.vercel.app/api/inngest
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]docker build -t spliter .
docker run -p 3000:3000 --env-file .env.local spliternpm run dev # Start development server (hot reload)
npm run build # Build for production
npm run start # Start production server
npm run lint # Run ESLint
npx convex dev # Start Convex local dev server
npx convex deploy # Deploy Convex functions to productionWhy Convex over a traditional database? Real-time sync is core to Splitr — when a friend adds an expense, you see it instantly. Convex handles WebSocket subscriptions automatically with no extra setup.
Why Clerk over Auth.js / NextAuth? Clerk provides production-grade auth (MFA, social logins, user management UI) with minimal code. For an expense app where trust matters, this is the right tradeoff.
Why Inngest for background jobs? CRON jobs on serverless platforms (Vercel) are unreliable. Inngest gives reliable scheduling, retries, and full observability — critical for payment reminders that must actually send.
Why Gemini AI over OpenAI? Gemini's free tier is generous enough for batch weekly insight generation at zero cost during development and low-traffic phases.
- Fork the repository
- Create a feature branch:
git checkout -b feature/your-feature - Commit changes:
git commit -m 'Add: your feature description' - Push:
git push origin feature/your-feature - Open a Pull Request
- RoadsideCoder for the original tutorial inspiration
- Convex for real-time database infrastructure
- Clerk for authentication
- Inngest for background job orchestration
- Shadcn UI for the component library
- Resend for email delivery
Built with ❤️ — Splitr: Split expenses. Simplify life.