A modern, full-featured personal expense tracking web application built with Next.js 14, TypeScript, and PostgreSQL.
- Dashboard: Overview of your expenses with interactive charts and summary cards
- CSV Import: Upload and parse CSV files from multiple credit card institutions (Fidelity, Costco Citi, American Express)
- Transaction Management: View, search, filter, and edit all your transactions with a powerful data table
- Dark/Light Mode: Toggle between themes with persistent preference storage
- Responsive Design: Mobile-friendly interface that works on all devices
- Type-Safe: Full TypeScript implementation with comprehensive type checking
- Database-Backed: PostgreSQL database with Prisma ORM for reliable data storage
- Framework: Next.js 14+ (App Router)
- Language: TypeScript
- Styling: Tailwind CSS
- UI Components: Radix UI
- Database: PostgreSQL
- ORM: Prisma
- Charts: Recharts
- Tables: Tanstack Table (React Table v8)
- Validation: Zod
- CSV Parsing: PapaParse
- Date Handling: date-fns
- Theming: next-themes
Before you begin, ensure you have the following installed:
- Node.js 18+ and npm
- PostgreSQL 14+ (local or remote instance)
- Git
git clone <your-repo-url>
cd expense-trackernpm installCreate a .env file in the root directory (or update the existing one):
DATABASE_URL="postgresql://username:password@localhost:5432/expense_tracker"Replace username, password, and database details with your PostgreSQL credentials.
Create the database (if it doesn't exist):
# Using psql
psql -U postgres
CREATE DATABASE expense_tracker;
\qRun Prisma migrations to create the database schema:
npx prisma migrate dev --name initThis will:
- Create all necessary tables (Account, Transaction, CSVMapping, Category, ImportHistory)
- Generate the Prisma Client
- Set up indexes for performance
You can manually add test data or create accounts through the application once it's running.
npm run devOpen http://localhost:3000 in your browser.
The application uses the following main models:
- Stores credit card and bank account information
- Fields: id, name, institution, accountType
- Individual transaction records
- Fields: id, accountId, date, description, amount, category, merchant, originalData (JSON)
- Indexed by: date, accountId, category
- Stores field mappings for different CSV formats
- Fields: id, institution (unique), fieldMapping (JSON), dateFormat
- Hierarchical categories for organizing transactions
- Fields: id, name, parentId (self-referential)
- Tracks CSV import operations
- Fields: id, fileName, institution, accountId, rowsImported, importedAt
The application supports the following CSV formats:
- Columns: Date, Description, Amount, Balance
- Date Format: MM/DD/YYYY
- Columns: Status, Date, Description, Debit, Credit
- Date Format: MM/DD/YYYY
- Columns: Date, Description, Card Member, Account #, Amount
- Date Format: MM/DD/YYYY
To add support for additional institutions, update the defaultMappings in lib/csv-parser.ts.
expense-tracker/
├── app/ # Next.js App Router pages
│ ├── api/ # API routes
│ │ ├── upload/ # CSV upload endpoint
│ │ ├── transactions/ # Transaction CRUD endpoints
│ │ ├── dashboard/ # Dashboard data endpoint
│ ├── import/ # CSV import page
│ ├── transactions/ # Transactions list page
│ ├── accounts/ # Accounts page
│ ├── layout.tsx # Root layout
│ ├── page.tsx # Dashboard page
│ └── globals.css # Global styles
├── components/ # React components
│ ├── ui/ # Base UI components (Button, Card, Input, etc.)
│ ├── app-shell.tsx # Main app layout
│ ├── nav.tsx # Navigation menu
│ ├── theme-toggle.tsx # Dark/light mode toggle
│ ├── csv-uploader.tsx # CSV upload component
│ ├── transactions-table.tsx # Transaction data table
│ ├── dashboard-charts.tsx # Dashboard charts
│ └── ...
├── lib/ # Utility functions and configurations
│ ├── prisma.ts # Prisma client singleton
│ ├── csv-parser.ts # CSV parsing logic
│ ├── validations.ts # Zod validation schemas
│ ├── utils.ts # Utility functions
│ └── generated/ # Generated Prisma Client
├── prisma/
│ └── schema.prisma # Database schema
├── types/
│ └── index.ts # TypeScript type definitions
└── public/ # Static assets
Upload and parse CSV files. Optionally import transactions if accountId is provided.
Body (FormData):
file: CSV fileinstitution: Institution name (fidelity, citi, amex)accountId: (optional) Account ID to import to
Fetch transactions with filtering and pagination.
Query Parameters:
startDate,endDate: Date range filteraccountId: Filter by accountcategory: Filter by categoryminAmount,maxAmount: Amount range filtersearch: Search in description/merchantpage,pageSize: Pagination
Update a transaction (category, merchant, description).
Delete a transaction.
Get dashboard summary data for a specific month.
Query Parameters:
month: (optional) Month to fetch data for (YYYY-MM format)
# Start development server
npm run dev
# Build for production
npm run build
# Start production server
npm start
# Run linter
npm run lint
# Generate Prisma Client
npx prisma generate
# Create a new migration
npx prisma migrate dev --name <migration-name>
# Open Prisma Studio (database GUI)
npx prisma studio- Update
types/index.tsto add the new institution type - Add the CSV mapping to
lib/csv-parser.tsin thedefaultMappingsobject - Add the institution option to the select dropdown in
components/csv-uploader.tsx
Categories can be managed through the Prisma Studio or by creating a categories management page in the application.
The theme colors are defined in app/globals.css. You can modify the CSS variables for both light and dark modes to match your preferred color scheme.
- Verify your
DATABASE_URLin.envis correct - Ensure PostgreSQL is running
- Check that the database exists
- Run
npx prisma generateto regenerate the client - Try deleting
node_modulesand runningnpm installagain
- Verify the CSV format matches the expected format for the institution
- Check the browser console for detailed error messages
- Use the preview feature to validate the CSV before importing
- User authentication and multi-user support
- Budget tracking and alerts
- Recurring transaction detection
- Export functionality (PDF reports, Excel)
- Mobile app
- Receipt image upload and OCR
- Bank account integration via Plaid
- Advanced analytics and insights
- Category auto-categorization with ML
Contributions are welcome! Please open an issue or submit a pull request.
MIT License - feel free to use this project for personal or commercial purposes.