A personal expense tracking dashboard that automatically parses Indian bank alert emails using Gmail API and Google Gemini AI to extract and categorize debit transactions.
Built with Next.js 16, React 19, Prisma, and Tailwind CSS.
- Automatic email parsing — Fetches bank alert emails from Gmail and extracts transactions using Gemini AI with structured output
- AI-powered categorization — Transactions are automatically categorized into 13 default categories with confidence scoring
- Review workflow — Low-confidence extractions (< 80%) are flagged for manual review with approve/edit/delete actions
- Manual entry — Add transactions manually when needed
- Monthly dashboard — Summary cards, category breakdown pie chart, and daily spending bar chart
- Credit card payment tracking — CC payments are tracked separately and excluded from spend totals to avoid double-counting
- Duplicate detection — Deduplicates by email message ID and flags potential same-day/amount/merchant matches
- Custom categories — Create new categories on the fly
- Single-user auth — Simple password-based authentication via NextAuth v5
Out of the box, the email parser targets:
- HDFC Bank —
alerts@hdfcbank.net,alerts@hdfcbank.bank.in - IDFC FIRST Bank —
noreply@idfcfirstbank.com,delivery.idfcfirstbank.com
You can add support for other banks by setting the GMAIL_SEARCH_QUERY environment variable with a custom Gmail search query.
- Framework: Next.js 16 (App Router, Server Components, Server Actions)
- Language: TypeScript (strict mode)
- Database: PostgreSQL via Prisma 7
- AI: Google Gemini 2.5 Flash via Vercel AI SDK
- Email: Gmail API (OAuth 2.0)
- Auth: NextAuth v5 (credentials provider)
- UI: Tailwind CSS 4, shadcn/ui, Recharts, Lucide icons
- Validation: Zod 4
- Node.js 18+
- PostgreSQL database
- Google Cloud project with Gmail API enabled
- Gemini API key
git clone https://github.com/narendran-kannan/expense-tracker.git
cd expense-tracker
npm installcp .env.example .envEdit .env with your values. See .env.example for detailed descriptions of each variable.
Key variables:
| Variable | Description |
|---|---|
DATABASE_URL |
PostgreSQL connection string |
AUTH_SECRET |
Random secret for NextAuth (openssl rand -base64 32) |
AUTH_PASSWORD |
Your dashboard login password |
GOOGLE_GENERATIVE_AI_API_KEY |
Gemini API key from AI Studio |
GMAIL_CLIENT_ID |
Gmail OAuth 2.0 client ID |
GMAIL_CLIENT_SECRET |
Gmail OAuth 2.0 client secret |
GMAIL_REFRESH_TOKEN |
Gmail refresh token (use OAuth Playground) |
CRON_SECRET |
Secret to protect the email processing endpoint |
npx prisma generate
npx prisma db push
npm run db:sync-categoriesnpm run devOpen http://localhost:3000 and log in with your AUTH_PASSWORD.
Click the "Seed Sample Data" button on the dashboard in development mode, or run:
curl -X POST http://localhost:3000/api/seedThe /api/process-emails endpoint fetches and parses bank alert emails. You can trigger it:
Manually (dev):
curl http://localhost:3000/api/process-emailsAs a cron job (production):
curl -H "Authorization: Bearer $CRON_SECRET" https://your-domain.com/api/process-emailsSupports ?dry_run=true to preview without saving and ?verbose=true for detailed logs.
- Go to Google Cloud Console
- Create a new project (or select an existing one)
- Enable the Gmail API
- Create OAuth 2.0 credentials (Desktop app type)
- Go to OAuth Playground
- Configure it to use your own OAuth credentials (gear icon)
- Authorize the
https://www.googleapis.com/auth/gmail.modifyscope - Exchange the authorization code for a refresh token
- Add the client ID, client secret, and refresh token to your
.env
Deploy to any platform that supports Next.js. For Vercel:
npm run buildSet all environment variables from .env.example in your deployment platform's settings.
Important:
npm run buildis the canonical production-safe deployment command.- It runs
prisma generate,prisma migrate deploy, category sync, andnext build. - Do not use
prisma db pushin production. - Run
npm run db:sync-categoriesafter introducing new default categories if needed. - Run
npm run db:backfill-categories:dryandnpm run db:backfill-categorieswhen upgrading older installs that predate category hierarchy support.
See DEPLOYMENT.md and UPGRADING.md for the full deployment and upgrade standard.