A local-first, privacy-focused way to manage credit card spend across multiple banks, built with Next.js and PostgreSQL.
Supports Chase and Capital One CSV exports.
⚠️ Work in progress, local use only. This project is intended to run on your own machine against a local database. API routes have no authentication. If hosted, anyone who can reach the server can read or modify your transactions. The Docker Compose setup ships with default dev credentials that are not safe for any deployed environment. Don't expose this to the public internet as-is.
- Drag & Drop CSV Upload: Upload transaction CSV files with a modern drag-and-drop interface
- Account Management: Create and manage multiple bank accounts
- Transaction Preview: Preview transactions before import with duplicate detection
- Multi-Bank Support: Supports Chase and Capital One CSV formats
- Frontend: Next.js 14, React, TypeScript, Tailwind CSS
- Backend: Next.js API Routes, Prisma ORM
- Database: PostgreSQL
- File Upload: react-dropzone
- Node.js 20+ (use
nvm use 20if you have nvm) - Docker and Docker Compose
- npm or yarn
-
Install dependencies:
npm install
-
Set up the database:
# Start PostgreSQL with Docker docker-compose up -d # Generate Prisma client npm run db:generate # Run database migrations npm run db:push
-
Set up environment variables:
# Copy the example environment file cp env.example .env.local # The default DATABASE_URL should work with the docker-compose setup
-
Start the development server:
npm run dev
-
Open your browser: Navigate to http://localhost:3000
- Go to the "Accounts" page
- Click "Add Account"
- Fill in the account details:
- Account Name: e.g., "Chase Sapphire ****1234"
- Bank Type: Select Chase or Capital One
- Table Key: Unique identifier (e.g., "chase_1234")
- Go to the main "Upload" page
- Select an account from the dropdown
- Drag and drop a CSV file or click to select
- Preview the parsed transactions
- Review any duplicate warnings
- Click "Confirm Import" to save to the database
Chase Bank:
Transaction Date,Post Date,Description,Category,Type,Amount
8/17/25,8/17/25,LYFT *1 RIDE 08-15,Travel,Sale,-21.1
Capital One:
Transaction Date,Posted Date,Card No.,Description,Category,Debit,Credit
8/17/25,8/17/25,****1234,LYFT *1 RIDE 08-15,Travel,21.1,
# View database in Prisma Studio
npm run db:studio
# Reset database
npm run db:push --force-reset
# Generate new migration
npm run db:migrate- Ensure Docker is running:
docker-compose ps - Check database logs:
docker-compose logs postgres - Verify DATABASE_URL in
.env.local
- Ensure CSV has correct headers for your bank type
- Check that dates are in MM/DD/YY format
- Verify amount format (no currency symbols)
- Clear Next.js cache:
rm -rf .next - Reinstall dependencies:
rm -rf node_modules && npm install - Check Node.js version:
node --version(should be 20+)
- Transaction viewing and search
- Export functionality
- Multi-file batch upload