A full-stack bill-splitting application that uses OCR and AI to extract receipt items and intelligently split payments among users.
Live Demo: https://splitimize.zawko.dev
- OCR Receipt Parsing: Upload receipt images and extract items automatically using Tesseract.js & OCR.space
- AI-Powered Extraction: Google Gemini LLM processes extracted text to identify items and prices
- Easy Bill Splitting: Split bills by item or equally among participants
- Authentication: OAuth integration with Google and GitHub via better-auth
- Demo Mode: Try the app instantly without signing up
- Responsive Design: Works seamlessly on desktop and mobile
- Dark Mode Support: Built-in theme switching
This is a monorepo project with three packages:
Splitimize-Fullstack/
├── frontend-nextjs/ # Next.js 15 React frontend
├── backend-express/ # Express.js TypeScript backend
├── shared/ # Shared TypeScript types & schemas
└── package.json # Workspace configuration
frontend-nextjs/
├── app/ # Next.js app directory
├── components/ # React components
├── lib/ # Utilities and client libraries
├── hooks/ # Custom React hooks
├── contexts/ # React contexts
├── config/ # Configuration files
└── public/ # Static assets
backend-express/
├── src/
│ ├── app.ts # Express app setup
│ ├── server.ts # Server entry point
│ ├── routes/ # API routes
│ ├── controllers/ # Request handlers
│ ├── services/ # Business logic
│ ├── models/ # Data models
│ ├── middleware/ # Custom middleware
│ └── lib/ # Utilities
├── prisma/
│ └── schema.prisma # Database schema
└── generated/ # Generated files (Prisma client, etc.)
shared/
└── src/
├── schema/ # Shared types and schemas
└── index.ts # Exports
Frontend:
- Next.js 15 with App Router
- React 19
- TypeScript
- Tailwind CSS
- Shadcn components
- TanStack React Query
- better-auth (auth client)
Backend:
- Express.js
- TypeScript
- PostgreSQL with Prisma ORM
- better-auth (auth server)
- Tesseract.js (OCR) & OCR.space (API)
- Google Gemini LLM
- Node.js 18+
- npm
- PostgreSQL database
- Google OAuth credentials
- GitHub OAuth credentials (optional)
- Google Gemini API key
-
Clone the repository:
git clone https://github.com/zwnkoko/Splitimize-Fullstack.git cd Splitimize-Fullstack -
Install dependencies:
npm install
-
Set up environment variables:
Backend (.env file in
backend-express/):cp backend-express/.env.example backend-express/.env
Frontend (.env.local file in
frontend-nextjs/):cp frontend-nextjs/.env.example frontend-nextjs/.env.local
Fill in your credentials in both
.envfiles (see sections below). -
Database Setup:
cd backend-express npx prisma migrate dev cd ..
Start both frontend and backend in development mode:
npm run devThis runs:
- Frontend: http://localhost:3000
- Backend: http://localhost:3001
Or run individually:
npm run dev:frontend # Frontend only
npm run dev:backend # Backend only
npm run dev:shared # Watch shared package changesnpm run build:frontend
npm run build:backendThen start:
npm run start --workspace=frontend-nextjs
npm run start --workspace=backend-expressSee backend-express/.env.example for the complete template.
Required:
BETTER_AUTH_SECRET- Secret used by better-auth for signingBETTER_AUTH_URL- Public URL of the auth server (usually backend URL)DATABASE_URL- PostgreSQL connection stringFRONTEND_URL- Frontend URL (for CORS and OAuth redirect)GOOGLE_CLIENT_ID- Google OAuth client IDGOOGLE_CLIENT_SECRET- Google OAuth client secretGITHUB_CLIENT_ID- GitHub OAuth client IDGITHUB_CLIENT_SECRET- GitHub OAuth client secretGEMINI_API_KEY- Google Gemini API key (for post-OCR parsing)OCR_SPACE_API_KEY- OCR.space API key (for image text extraction)
Optional:
PORT- Server port (default: 3001)NODE_ENV- Environment mode (default: development)
See frontend-nextjs/.env.example for the complete template.
Required:
NEXT_PUBLIC_API_BASE_URL- Backend API base URL
- Go to Google Cloud Console
- Create a new project
- Enable the Google+ API
- Create OAuth 2.0 credentials (Web application)
- Add authorized redirect URIs:
http://localhost:3001/api/auth/callback/google(development)https://your-domain.com/api/auth/callback/google(production)
- Copy the Client ID and Secret to your
.env
- Go to GitHub Settings
- Create a new OAuth App
- Set Authorization callback URL:
http://localhost:3001/api/auth/callback/github(development)https://your-domain.com/api/auth/callback/github(production)
- Copy the Client ID and Secret to your
.env
- User uploads receipt image (JPG, PNG, HEIC)
- Frontend compresses image and sends to backend
- Backend extracts text using Tesseract.js
- Google Generative AI parses the extracted text
- Frontend displays extracted items for confirmation/editing
- User can split by item or equally
- OAuth Flow: Google/GitHub → better-auth → PostgreSQL
- Session Management: HTTP-only cookies
- Demo Mode: Local storage flag for quick testing
Run tests:
npm run test --workspace=frontend-nextjs
npm run test:watch --workspace=frontend-nextjs