A full-stack web application to track, manage, and visualize all your recurring subscriptions in one place. Built with React on the frontend and Node.js + Express + MongoDB on the backend, featuring a dark-mode UI, spending analytics, and a real-time dashboard.
- Features
- Tech Stack
- Project Structure
- Prerequisites
- Setup & Installation
- Environment Variables
- Running the Application
- API Reference
- Data Model
- Authors
- Subscription CRUD — Add, view, edit, and delete subscriptions with name, category, price, frequency, status, and description
- Dashboard Overview — Stat cards showing total active subscriptions, monthly spending, and yearly spending
- Spending Charts — Bar charts for the last 12 months of total spending and 6-month forward projection (powered by Recharts)
- Category Support — Organize subscriptions by Entertainment, Productivity, Fitness, Education, Streaming, or Other
- Billing Frequency — Track both monthly and yearly subscriptions; yearly costs are automatically prorated for monthly charts
- Auto Next Billing Date — Calculated automatically on the backend based on start date and frequency
- Status Tracking — Mark subscriptions as active, paused, or cancelled
- Notification Center — In-app notifications for subscription actions
- Dark Mode Only — Locked to a clean dark theme throughout
- Error Boundary — Graceful error handling in the React component tree
- Health Check Endpoint —
GET /api/healthfor server status monitoring
| Layer | Technology |
|---|---|
| Frontend | React 19, Vite, Tailwind CSS, Recharts, Framer Motion, GSAP |
| Routing | React Router DOM v7 |
| HTTP Client | Fetch API (native) |
| Backend | Node.js, Express 4 |
| Database | MongoDB with Mongoose 8 |
| Environment | dotenv |
| Dev Server | node --watch (no nodemon needed) |
Subscription-Manager/
│
├── my-app/ # React frontend (Vite)
│ ├── src/
│ │ ├── pages/
│ │ │ ├── DashboardPage.jsx # Stats cards + spending bar charts
│ │ │ └── AllSubscriptionPage.jsx # Full subscription list
│ │ ├── Component/
│ │ │ ├── Layout.jsx # App shell with sidebar
│ │ │ ├── Sidebar.jsx # Navigation sidebar
│ │ │ ├── StatCard.jsx # Stat display card
│ │ │ ├── SubscriptionCard.jsx # Individual subscription tile
│ │ │ ├── AddSubscriptionModal.jsx
│ │ │ ├── EditSubscriptionModal.jsx
│ │ │ ├── NotificationCenter.jsx
│ │ │ ├── NavItem.jsx
│ │ │ └── ErrorBoundary.jsx
│ │ ├── Context/
│ │ │ └── SubscriptionContext.jsx # Global state & stats helpers
│ │ ├── services/
│ │ │ └── api.js # All fetch calls to the backend
│ │ └── App.jsx # Routes + providers
│ ├── package.json
│ └── vite.config.js
│
├── server/ # Node.js + Express backend
│ ├── server.js # Entry point, middleware, routes
│ ├── config/
│ │ └── db.js # MongoDB connection
│ ├── models/
│ │ └── Subscription.js # Mongoose schema
│ ├── controllers/
│ │ └── subscriptionController.js # All route logic
│ ├── routes/
│ │ └── subscriptions.js # Route definitions
│ └── package.json
│
└── README.md
- Node.js v18 or higher
- MongoDB — local instance on port
27017, or a MongoDB Atlas connection string
1. Clone the repository
git clone https://github.com/PuneethYenneti06/Subscription-Manager.git
cd Subscription-Manager2. Install backend dependencies
cd server
npm install3. Install frontend dependencies
cd ../my-app
npm install4. Configure environment variables (see below)
Create a .env file inside the server/ directory:
MONGODB_URI=mongodb://localhost:27017/subscription-manager
PORT=5000For MongoDB Atlas, replace the URI with your connection string:
MONGODB_URI=mongodb+srv://<username>:<password>@cluster0.xxxxx.mongodb.net/subscription-managerThe
server/.envfile is excluded from version control via.gitignore.
Open two terminals and run each command in parallel:
Terminal 1 — Backend
cd server
npm run dev
# Server running on http://localhost:5000Terminal 2 — Frontend
cd my-app
npm run dev
# App running on http://localhost:5173Then open http://localhost:5173 in your browser.
All endpoints are prefixed with /api. The backend runs on port 5000.
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/subscriptions |
Get all subscriptions |
POST |
/api/subscriptions |
Create a new subscription |
GET |
/api/subscriptions/:id |
Get a single subscription |
PUT |
/api/subscriptions/:id |
Update a subscription |
DELETE |
/api/subscriptions/:id |
Delete a subscription |
GET |
/api/subscriptions/stats/overview |
Get active count + spending totals |
GET |
/api/subscriptions/stats/monthly-chart |
Get 6-month forward spending projection |
GET |
/api/subscriptions/stats/yearly-chart |
Get last 12 months of spending data |
GET |
/api/health |
Server health check |
Request
curl -X POST http://localhost:5000/api/subscriptions \
-H "Content-Type: application/json" \
-d '{
"name": "Netflix",
"category": "Streaming",
"price": 649,
"frequency": "monthly",
"description": "Standard plan"
}'Response
{
"success": true,
"message": "Subscription added successfully",
"data": {
"_id": "664f1a...",
"name": "Netflix",
"category": "Streaming",
"price": 649,
"frequency": "monthly",
"status": "active",
"nextBillingDate": "2025-07-09T00:00:00.000Z",
"createdAt": "2025-06-09T00:00:00.000Z"
}
}| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
name |
String | ✅ | — | Subscription service name |
category |
String | — | Other |
Entertainment, Productivity, Fitness, Education, Streaming, Other |
price |
Number | ✅ | — | Must be ≥ 0 |
frequency |
String | — | monthly |
monthly or yearly |
status |
String | — | active |
active, paused, or cancelled |
startDate |
Date | — | Now | When billing started |
endDate |
Date | — | null |
Optional billing end date |
nextBillingDate |
Date | — | Auto-calculated | Set automatically on first save |
description |
String | — | — | Optional notes |
userId |
ObjectId | ✅ | — | Linked user (shared default ID in public-access mode) |
nextBillingDate is auto-calculated on first save: +1 month for monthly, +1 year for yearly.
- Prathamesh Kumar Singh
- Puneeth Yenneti
- Pruthviraj Ajay Patil