A modern subscription tracker built with Next.js 16, designed to help you monitor, manage, and analyze all your recurring expenses in one place.
- Subscription Management — Add, edit, and delete subscriptions with real-time updates
- Multi-Currency Support — Track subscriptions in different currencies with automatic conversion via Frankfurter API
- Dashboard Analytics — Spending distribution, billing calendar, and monthly trend charts
- Export Data — Download your data as Excel (.xlsx), CSV, or JSON
- Audit Log — Full event history for every subscription change (create, update, delete)
- Authentication — Email/password and OAuth (Google, GitHub) via Better Auth
- Responsive Design — Fully responsive UI built with shadcn/ui and Base UI
| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router) |
| Language | TypeScript |
| Database | Neon (Serverless PostgreSQL) |
| ORM | Drizzle |
| Auth | Better Auth |
| UI | shadcn/ui + Base UI |
| State | TanStack React Query + Jotai |
| Styling | Tailwind CSS v4 |
| Validation | Zod + React Hook Form |
# Clone the repository
git clone https://github.com/mrluisfer/cusana.git
cd cusana
# Install dependencies
pnpm install
# Set up environment variables
cp .env.example .env.localEdit .env.local with your credentials. See Environment Variables for details.
# Push the database schema
pnpm db:push
# Start the development server
pnpm devOpen http://localhost:3000 to see the app.
| Variable | Required | Description |
|---|---|---|
DATABASE_URL |
Yes | Neon PostgreSQL connection string |
BETTER_AUTH_SECRET |
Yes | Auth secret — generate with openssl rand -base64 32 |
BETTER_AUTH_URL |
Yes | Base URL of your app (e.g. http://localhost:3000) |
NEXT_PUBLIC_BETTER_AUTH_URL |
Yes | Public base URL (same as above) |
GOOGLE_CLIENT_ID |
No | Google OAuth client ID |
GOOGLE_CLIENT_SECRET |
No | Google OAuth client secret |
GITHUB_CLIENT_ID |
No | GitHub OAuth client ID |
GITHUB_CLIENT_SECRET |
No | GitHub OAuth client secret |
| Command | Description |
|---|---|
pnpm dev |
Start development server |
pnpm build |
Build for production |
pnpm start |
Start production server |
pnpm lint |
Run ESLint |
pnpm type-check |
Run TypeScript type checking |
pnpm format |
Format code with Prettier |
pnpm db:generate |
Generate Drizzle migrations |
pnpm db:push |
Push schema to database |
pnpm db:migrate |
Run pending migrations |
pnpm db:studio |
Open Drizzle Studio |
cusana/
├── app/
│ ├── (auth)/ # Auth pages (login, register)
│ ├── (protected)/ # Authenticated routes
│ │ └── dashboard/
│ │ └── components/
│ │ ├── resume/ # Dashboard summary cards
│ │ └── subscriptions/ # Data table & actions
│ └── api/ # API routes
├── components/
│ ├── dashboard/ # Shared dashboard components
│ └── ui/ # shadcn/ui components
├── constants/ # App constants (icons, currencies)
├── hooks/ # Custom React hooks
├── lib/
│ ├── auth.ts # Better Auth configuration
│ ├── db.ts # Drizzle + Neon client
│ ├── schema.ts # Database schema
│ └── queries/ # Database query helpers
├── utils/ # Utility functions
└── drizzle/ # Migrations
The recommended deployment target is Vercel:
- Push your repo to GitHub
- Import the project in Vercel
- Add your environment variables
- Deploy
Contributions are welcome! Please read the Contributing Guide before submitting a pull request.
This project is licensed under the MIT License.