A modern, full-stack expense sharing application that makes splitting bills and tracking group expenses effortless. Built with NestJS and Next.js for optimal performance and developer experience.
- π₯ Group Management - Create and manage expense groups with unique invite codes for easy collaboration
- π° Expense Tracking - Add, edit, and delete expenses with support for multiple participants and custom splits
- π Smart Balance Calculation - Automatic balance calculation using optimized algorithms to minimize transactions
- π·οΈ Budget Categories - 20+ predefined categories with personal budget limits and spending alerts
- π± Activity Feed - Real-time activity stream showing all group transactions and updates
- π Secure Authentication - JWT-based authentication with secure password hashing
- π File Uploads - Attach receipts, invoices, and proof images (JPG, PNG, PDF up to 5MB)
- π³ Settlement Tracking - Mark settlements as pending or completed with optional proof images
- β‘ Optimized Settlements - Greedy algorithm minimizes the number of transactions needed to settle all debts
- π Spending Analytics - Track spending by category with visual budget indicators
- π Search & Filter - Find users, groups, and expenses quickly
- π¨ Dark Mode Support - Eye-friendly interface with theme switching
- π± Responsive Design - Works seamlessly on desktop, tablet, and mobile devices
- NestJS - Progressive Node.js framework for building efficient server-side applications
- TypeORM - TypeScript ORM for database management with automatic migrations
- PostgreSQL - Robust relational database for data persistence
- JWT - Secure token-based authentication
- Multer - Middleware for handling multipart/form-data file uploads
- bcrypt - Password hashing for secure user authentication
- class-validator - Declarative validation for DTOs
- Next.js 16 - React framework with Turbopack for blazing-fast development
- TypeScript - Type-safe JavaScript for better developer experience
- Tailwind CSS - Utility-first CSS framework for rapid UI development
- Zustand - Lightweight state management with persistence
- Axios - Promise-based HTTP client with interceptors
- React Hooks - Modern React patterns for state and effects
Before you begin, ensure you have installed:
- Node.js (v18 or higher) - Download here
- npm or yarn - Package manager (comes with Node.js)
- PostgreSQL (v14 or higher) - Download here
- Git - Version control system
# Clone the repository
git clone https://github.com/Chaksterr/minisplit.git
# Navigate to project directory
cd minisplit# Navigate to backend directory
cd backend
# Install dependencies
npm installCreate a .env file in the backend directory with the following configuration:
# Database Configuration
DB_HOST=localhost
DB_PORT=5432
DB_USERNAME=your_db_user
DB_PASSWORD=your_db_password
DB_DATABASE=minisplit
# JWT Configuration
JWT_SECRET=your_very_secure_secret_key_here_min_32_chars
JWT_EXPIRATION=7d
# Server Configuration
PORT=3001
NODE_ENV=development
β οΈ Security Note: Make sure to use a strong, unique JWT_SECRET in production (minimum 32 characters)
# Navigate to frontend directory (from project root)
cd frontend
# Install dependencies
npm installCreate a .env.local file in the frontend directory:
# API Configuration
NEXT_PUBLIC_API_URL=http://localhost:3001Create a PostgreSQL database for the application:
# Connect to PostgreSQL
psql -U postgres
# Create database
CREATE DATABASE minisplit;
# (Optional) Create dedicated user
CREATE USER minisplit_user WITH PASSWORD 'your_password';
GRANT ALL PRIVILEGES ON DATABASE minisplit TO minisplit_user;
# Exit
\qπ‘ Note: The application will automatically run TypeORM migrations on first start, creating all necessary tables.
# From backend directory
cd backend
npm run start:devThe backend server will start on http://localhost:3001 with hot-reload enabled.
Expected Output:
π Backend dΓ©marrΓ© sur http://localhost:3001
[Nest] Starting Nest application...
[Nest] Nest application successfully started
# From frontend directory (open new terminal)
cd frontend
npm run devThe frontend will start on http://localhost:3000 with Turbopack for fast refresh.
Access the application at: http://localhost:3000
# Backend
cd backend
npm run build
npm run start:prod
# Frontend
cd frontend
npm run build
npm start-
Register Account
- Navigate to http://localhost:3000/auth/register
- Fill in username, email, and password
- Click "Create Account"
-
Create Your First Group
- After login, go to "Groups" page
- Click "Create New Group"
- Enter group name and description
- Share the generated invite code with friends
-
Add Expenses
- Select a group from your dashboard
- Click "Add Expense"
- Enter title, amount, and select participants
- Choose a category and optionally attach receipts
- Click "Create Expense"
-
View Balances
- In the group view, see "Who Owes What" section
- Review the optimized settlement plan
- See exactly who needs to pay whom
-
Settle Debts
- When payments are made, mark them as settled
- Optionally add proof images
- Balances update automatically
minisplit/
βββ backend/ # NestJS Backend Application
β βββ src/
β β βββ auth/ # JWT authentication & authorization
β β βββ user/ # User profile management
β β βββ group/ # Group CRUD operations
β β βββ group-member/ # Group membership management
β β βββ expense/ # Expense tracking & file uploads
β β βββ category/ # Budget categories & limits
β β βββ balance/ # Balance calculation engine
β β βββ settlement/ # Debt settlement tracking
β β βββ activity/ # Activity feed logging
β β βββ common/ # Shared utilities & guards
β βββ uploads/ # Uploaded files (avatars, receipts)
β βββ .env # Environment variables (not tracked)
β βββ package.json # Backend dependencies
β
βββ frontend/ # Next.js Frontend Application
β βββ src/
β β βββ app/ # Next.js 16 App Router pages
β β β βββ auth/ # Login & registration pages
β β β βββ groups/ # Group management pages
β β β βββ expenses/ # Expense pages
β β β βββ categories/ # Budget category pages
β β β βββ profile/ # User profile page
β β βββ components/ # Reusable React components
β β β βββ ui/ # Base UI components
β β β βββ layout/ # Layout components
β β β βββ auth/ # Auth-related components
β β βββ lib/ # API client & utilities
β β β βββ api.ts # Axios API configuration
β β β βββ store.ts # Zustand state management
β β β βββ utils.ts # Helper functions
β β βββ hooks/ # Custom React hooks
β βββ .env.local # Frontend environment variables
β βββ package.json # Frontend dependencies
β
βββ .gitignore # Git ignore rules (.env protected)
βββ README.md # Project documentation
The backend API runs on http://localhost:3001 with the following endpoints:
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /auth/register |
Register a new user | β |
| POST | /auth/login |
Login and get JWT token | β |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /users |
Get all users | β |
| GET | /users/:id |
Get user by ID | β |
| GET | /users/username/:username |
Get user by username | β |
| GET | /users/name/:name |
Search users by name | β |
| PUT | /users/:id |
Update user profile | β |
| DELETE | /users/:id |
Delete user account | β |
| POST | /users/:id/avatar |
Upload user avatar | β |
| DELETE | /users/:id/avatar |
Delete user avatar | β |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /groups |
Create a new group | β |
| GET | /groups |
Get all user's groups | β |
| GET | /groups/:id |
Get group by ID | β |
| GET | /groups/name/:name |
Search groups by name | β |
| GET | /groups/code/:code |
Get group by invite code | β |
| PUT | /groups/:id |
Update group details | β |
| DELETE | /groups/:id |
Delete group | β |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /group-members |
Add member to group | β |
| GET | /group-members/group/:groupId |
Get all group members | β |
| GET | /group-members/user/:userId |
Get user's group memberships | β |
| POST | /group-members/:id/promote |
Promote member to admin | β |
| DELETE | /group-members/:id |
Remove member from group | β |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /expenses |
Create new expense | β |
| GET | /expenses |
Get all expenses | β |
| GET | /expenses/:id |
Get expense by ID | β |
| GET | /expenses/group/:groupId |
Get all group expenses | β |
| PUT | /expenses/:id |
Update expense | β |
| DELETE | /expenses/:id |
Delete expense | β |
| POST | /expenses/:id/attachments |
Upload expense attachments | β |
| DELETE | /expenses/:id/attachments/:filename |
Delete attachment | β |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /categories |
Get all categories | β |
| GET | /categories/with-budgets |
Get categories with user budgets | β |
| GET | /categories/user/budgets |
Get user's budget settings | β |
| GET | /categories/:id |
Get category by ID | β |
| GET | /categories/:id/budget |
Get user budget for category | β |
| POST | /categories/:id/budget |
Set user budget for category | β |
| DELETE | /categories/:id/budget |
Remove user budget | β |
| POST | /categories |
Create new category | β |
| PUT | /categories/:id |
Update category | β |
| DELETE | /categories/:id |
Delete category | β |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /balances/group/:groupId |
Get group balances & settlement plan | β |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /settlements |
Create new settlement | β |
| GET | /settlements |
Get all settlements | β |
| GET | /settlements/:id |
Get settlement by ID | β |
| GET | /settlements/group/:groupId |
Get group settlements | β |
| GET | /settlements/user/:userId |
Get user settlements | β |
| PUT | /settlements/:id |
Update settlement | β |
| DELETE | /settlements/:id |
Delete settlement | β |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /activities |
Create activity log | β |
| GET | /activities |
Get all activities | β |
| GET | /activities/group/:groupId |
Get group activities | β |
| GET | /activities/user/:userId |
Get user activities | β |
POST /expenses
{
"title": "Dinner at Restaurant",
"amount": 120.50,
"description": "Team dinner",
"date": "2025-12-15",
"paidBy": 1,
"groupId": 5,
"participants": [1, 2, 3],
"categoryId": 8,
"splitType": "equal"
}POST /categories/8/budget
{
"budgetLimit": 500.00
}We welcome contributions! Here's how you can help:
-
Fork the repository
git fork https://github.com/Chaksterr/minisplit.git
-
Create a feature branch
git checkout -b feature/amazing-feature
-
Make your changes
- Follow the existing code style
- Add tests if applicable
- Update documentation as needed
-
Commit your changes
git commit -m 'feat: add amazing feature'Use conventional commits:
feat:- New featuresfix:- Bug fixesdocs:- Documentation changesrefactor:- Code refactoringtest:- Test additions/changeschore:- Maintenance tasks
-
Push to your fork
git push origin feature/amazing-feature
-
Open a Pull Request
- Describe your changes clearly
- Reference any related issues
- Wait for review and feedback
Backend won't start:
- Verify PostgreSQL is running:
sudo systemctl status postgresql - Check database credentials in
.env - Ensure port 3001 is available
Frontend can't connect to backend:
- Verify
NEXT_PUBLIC_API_URLin.env.local - Check backend is running on port 3001
- Clear browser cache and restart dev server
Database migration errors:
- Drop and recreate database if needed
- Check TypeORM configuration
- Ensure database user has proper permissions
This project is licensed under the MIT License - see the LICENSE file for details.
Chaksterr
- GitHub: @Chaksterr
β If you find this project helpful, please give it a star on GitHub!