AI-powered bill splitting with Google Gemini 2.0 Flash
Built with Next.js 14 · Supabase · NextAuth.js · Tailwind CSS · Vercel
- What You're Building
- Phase 0 — Prerequisites
- Phase 1 — Supabase Database
- Phase 2 — Google Gemini API Key
- Phase 3 — Google OAuth
- Phase 4 — Project Setup
- Phase 5 — Environment Variables
- Phase 6 — Run Locally
- Phase 7 — Deploy to Vercel
- Troubleshooting
- How the AI Features Work
SplitBase AI is a bill-splitting app powered by Google Gemini 2.0 Flash:
| Feature | How it works |
|---|---|
| 📝 Natural language expense entry | Type "Dinner $80, Alice had steak so +$20 for her" → Gemini parses it |
| 📸 Receipt photo scanning | Upload a photo → Gemini reads every line item automatically |
| 🤖 AI debt reminders | Gemini drafts human-sounding messages to collect what you're owed |
| 💬 AI chat assistant | Ask "What do I owe this month?" and get a real answer |
| 👥 Group management | Create groups, invite friends, track who owes whom |
You need these installed on your computer before starting.
Node.js is the JavaScript runtime that runs the app.
- Go to https://nodejs.org
- Download the LTS (Long-Term Support) version
- Run the installer, click "Next" through all steps
- Verify it worked: open Terminal (Mac) or Command Prompt (Windows) and type:
You should see something like
node --version
v20.11.0
Git is used to track your code.
- Mac: It's usually already installed. Type
git --versionto check. If not, install Xcode Command Line Tools:xcode-select --install - Windows: Download from https://git-scm.com and install
You'll need accounts on these services:
| Service | URL | What it's for |
|---|---|---|
| Supabase | https://supabase.com | Database (PostgreSQL) |
| Google Cloud | https://console.cloud.google.com | OAuth sign-in + Gemini AI |
| Vercel | https://vercel.com | Hosting/deployment |
| GitHub | https://github.com | Code storage (needed for Vercel) |
Supabase is your database. All groups, expenses, and user data is stored here.
- Go to https://supabase.com and click Start your project
- Sign in with GitHub
- Click New project
- Fill in:
- Organization: your username (auto-filled)
- Name:
splitbase-ai - Database Password: create a strong password (save it somewhere safe)
- Region: pick the closest to you
- Click Create new project
- Wait ~2 minutes for it to set up
This creates all the tables your app needs.
- In your Supabase project, click SQL Editor in the left sidebar
- Click New query
- Open the file
supabase/schema.sqlfrom this project - Copy the entire contents of that file
- Paste it into the SQL Editor
- Click the green Run button
- You should see "Success. No rows returned" — that's correct!
- In Supabase, click Storage in the left sidebar
- Click New bucket
- Name it exactly:
receipts - Toggle Public bucket to OFF (keep it private)
- Click Create bucket
- In Supabase, click Settings (gear icon) → API
- Find and copy these values — you'll need them in Phase 5:
Project URL: https://xxxxxxxxxxxx.supabase.co
anon public key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
service_role key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
⚠️ Important: Theservice_rolekey is secret — never share it publicly or commit it to Git.
Gemini is the AI brain of the app. It parses receipts, understands natural language, and drafts reminders.
- Go to https://aistudio.google.com/app/apikey
- Sign in with your Google account
- Click Create API key
- Copy the key — it looks like:
AIzaSyD...
✅ The free tier gives you 1,500 requests/day — more than enough for development and a hackathon demo.
This lets users sign in with their Google account (one click, no password).
- Go to https://console.cloud.google.com
- Click the project dropdown at the top → New Project
- Name it
SplitBase AI→ click Create
- In Google Cloud Console, go to APIs & Services → Library
- Search for "Google+ API" and click Enable
- Search for "Identity Toolkit API" and click Enable
- Go to APIs & Services → Credentials
- Click + CREATE CREDENTIALS → OAuth client ID
- If prompted, configure the consent screen first:
- User Type: External
- App name:
SplitBase AI - User support email: your email
- Developer contact: your email
- Click Save and Continue through all steps
- Back at Create OAuth Client ID:
- Application type: Web application
- Name:
SplitBase AI Web - Authorized redirect URIs — add these:
(replace
http://localhost:3000/api/auth/callback/google https://your-app.vercel.app/api/auth/callback/googleyour-appwith your actual Vercel URL — you can update this later)
- Click Create
- Copy your Client ID and Client Secret
- Unzip
splitbase-ai.zipto a folder on your computer - Open Terminal and navigate to that folder:
cd path/to/splitbase-ai
This downloads all the packages the app needs (~200MB, takes 1-3 minutes):
npm installYou should see a progress bar and then added X packages.
Environment variables are secret configuration values the app needs to run.
cp .env.example .env.localThis copies the template file. Now open .env.local in any text editor.
Replace every your_xxx_here with your actual values:
# Gemini AI (from Phase 2)
GEMINI_API_KEY=AIzaSyD_your_actual_key_here
# Supabase (from Phase 1, Step 4)
NEXT_PUBLIC_SUPABASE_URL=https://xxxxxxxxxxxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
# NextAuth (generate a random secret)
NEXTAUTH_SECRET=run_the_command_below_to_generate_this
NEXTAUTH_URL=http://localhost:3000
# Google OAuth (from Phase 3)
GOOGLE_CLIENT_ID=123456789-xxxxx.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=GOCSPX-xxxxxxxxxxxxx
# App URL
NEXT_PUBLIC_APP_URL=http://localhost:3000Run this command in Terminal and paste the output as your NEXTAUTH_SECRET:
Mac/Linux:
openssl rand -base64 32Windows (PowerShell):
[Convert]::ToBase64String([System.Security.Cryptography.RandomNumberGenerator]::GetBytes(32))npm run devYou should see:
▲ Next.js 14.x.x
- Local: http://localhost:3000
- Environments: .env.local
✓ Ready
Go to http://localhost:3000 in your browser.
You should see the SplitBase AI landing page! Click Get Started and sign in with Google.
- Sign in with Google
- Create a group — click "New Group", name it "Test Group"
- Add an expense — click "Add Expense" → "AI Entry"
- Type:
Dinner at Nobu $120, split equally between 3 people - Watch Gemini parse it in real-time!
- Test receipt scan — take a photo of any receipt, upload it under "Receipt Scan"
Vercel is where your app lives online. It auto-deploys every time you push code to GitHub.
- Create a new repository at https://github.com/new
- Name:
splitbase-ai - Keep it Private
- Don't initialize with README (your project already has files)
- Name:
- In Terminal:
git init git add . git commit -m "Initial commit: SplitBase AI" git branch -M main git remote add origin https://github.com/YOUR_USERNAME/splitbase-ai.git git push -u origin main
- Go to https://vercel.com → Add New Project
- Click Import next to your
splitbase-airepository - Keep all defaults, then click Deploy
- It will fail at first because it needs environment variables — that's OK!
- In Vercel, go to your project → Settings → Environment Variables
- Add every variable from your
.env.local, but change these two:NEXTAUTH_URL = https://your-actual-app.vercel.app NEXT_PUBLIC_APP_URL = https://your-actual-app.vercel.app - Click Save
- Go to Deployments → click Redeploy on the latest deployment
- Wait ~2 minutes
- Click the live URL — your app is live! 🎉
- Go back to Google Cloud Console → APIs & Services → Credentials
- Click your OAuth Client ID
- Add your Vercel URL to Authorized redirect URIs:
https://your-actual-app.vercel.app/api/auth/callback/google - Click Save
rm -rf node_modules .next
npm install
npm run dev- Check
GEMINI_API_KEYin.env.localis correct (no spaces, no quotes) - Make sure you enabled the Gemini API at aistudio.google.com
- Make sure
http://localhost:3000/api/auth/callback/googleis in your OAuth redirect URIs - Check
NEXTAUTH_URL=http://localhost:3000in.env.local
- Make sure you ran the full
schema.sql— it includes all RLS policies - Check
SUPABASE_SERVICE_ROLE_KEYis the fullservice_rolekey (not the anon key)
- Go to Supabase SQL Editor and re-run
schema.sql - Make sure the SQL ran without errors (green "Success" message)
- The Gemini API call happens server-side — check Vercel Function Logs
- Verify
GEMINI_API_KEYis set in Vercel environment variables
When you type "Dinner $80, Alice had steak so +$20":
- Your browser sends the text to
/api/ai/parse-expense - That route calls Gemini 2.0 Flash with a structured JSON schema
- Gemini returns:
{ total: 80, splits: [{ member: "Alice", amount: 40 }, ...], confidence: 0.9 } - The UI shows you the parsed result for confirmation before saving
When you upload a receipt photo:
- The image is converted to base64 in your browser
- Sent to
/api/ai/parse-receipt - That route calls Gemini with the image using multimodal vision
- Gemini reads every line item, subtotal, tax, tip, and total
- Returns structured JSON you can confirm and assign to members
When you click "Remind" on a debt:
- The debtor's name, amount, and context go to
/api/ai/draft-reminder - Gemini generates a friendly, human-sounding message in your chosen tone
- You can edit the draft before sending
The chat uses Vercel AI SDK's streaming with Gemini:
- Responses stream word-by-word (no waiting for the full response)
- Gemini has access to "tools" — functions that query your real database
- Ask "Who owes me the most?" and Gemini calls
getUserNetBalanceto get real data
splitbase-ai/
├── app/
│ ├── (auth)/login/ # Login page
│ ├── (dashboard)/
│ │ ├── dashboard/ # Main dashboard
│ │ └── groups/[groupId]/ # Group detail page
│ ├── api/
│ │ ├── ai/
│ │ │ ├── parse-expense/ # Gemini NLP parsing
│ │ │ ├── parse-receipt/ # Gemini vision
│ │ │ ├── draft-reminder/# Gemini reminder drafts
│ │ │ └── chat/ # Gemini streaming chat
│ │ ├── groups/ # Group CRUD
│ │ ├── expenses/ # Expense creation
│ │ └── settlements/ # Mark debts as paid
│ └── page.tsx # Landing page
├── components/
│ ├── ai/ # AI-powered UI components
│ ├── expenses/ # Expense list & dialogs
│ ├── groups/ # Group management UI
│ ├── layout/ # Navbar, providers
│ └── ui/ # Base components (Button, Card, etc.)
├── supabase/
│ ├── schema.sql # Full database schema with RLS
│ └── client.ts # Supabase client helpers
├── lib/utils.ts # Helper functions
├── types/index.ts # TypeScript types
├── auth.ts # NextAuth configuration
└── .env.example # Environment variable template
| Question | Answer |
|---|---|
| Where is my data stored? | Supabase (PostgreSQL in the cloud) |
| Where does the AI live? | Google Gemini API (called server-side) |
| Is my API key safe? | Yes — it's only on the server, never sent to browsers |
| How do users sign in? | Google OAuth or email magic link (via NextAuth.js) |
| Where is the app hosted? | Vercel (auto-deploys from GitHub) |
| Can I use it offline? | No — it requires internet for Gemini and Supabase |
| Does it cost money? | All free tiers are sufficient for development & demo |
SplitBase AI · Built with Next.js 14 + Gemini 2.0 Flash + Supabase + Vercel