A clean, fast subscription tracker built on Cloudflare's edge. Know exactly where your money goes every month.
- Track subscriptions β Add from built-in templates (Netflix, YouTube, Claude, etc.) or create custom entries
- Auto-calculate renewals β Next billing date updates automatically based on your billing cycle
- See your spending β Monthly/yearly totals, category breakdowns, upcoming renewals at a glance
- Google sign-in β One-click OAuth alongside email/password auth
| Layer | Tech |
|---|---|
| Framework | TanStack Start + React 19 + TypeScript |
| Database | Cloudflare D1 (SQLite) via Drizzle ORM |
| Auth | Better Auth with Google OAuth |
| UI | shadcn/ui + Tailwind CSS v4 |
| Animations | Motion |
| Validation | Zod |
| Deployment | Cloudflare Workers |
# Install dependencies
bun install
# Set up local secrets (create .dev.vars from example)
cp .env.example .dev.vars
# Then fill in your secrets in .dev.vars
# Run database migrations
bun run db:migrate
# Start dev server
bun run devApp runs at http://localhost:3002.
Non-secret config goes in .env. Secrets go in .dev.vars (local) or Wrangler secrets (production).
| Variable | Where | Description |
|---|---|---|
BETTER_AUTH_URL |
.env |
App URL (http://localhost:3002 for dev) |
BETTER_AUTH_SECRET |
.dev.vars |
Session signing key |
BETTER_AUTH_GOOGLE_CLIENT_ID |
.dev.vars |
Google OAuth client ID |
BETTER_AUTH_GOOGLE_CLIENT_SECRET |
.dev.vars |
Google OAuth client secret |
# Set production secrets (encrypted, nobody can read them back)
wrangler secret put BETTER_AUTH_SECRET
wrangler secret put BETTER_AUTH_URL
wrangler secret put BETTER_AUTH_GOOGLE_CLIENT_ID
wrangler secret put BETTER_AUTH_GOOGLE_CLIENT_SECRET
# Run migrations on production D1
bun run db:migrate:prod
# Deploy
bun run deployDon't forget to add your production callback URL in Google Cloud Console:
https://<your-worker>.workers.dev/api/auth/callback/google
src/
βββ routes/ # File-based routing
β βββ index.tsx # Landing page
β βββ login.tsx # Sign in
β βββ register.tsx # Sign up
β βββ _authed/ # Protected routes
β βββ dashboard.tsx
β βββ subscriptions/
βββ components/ # UI components
βββ server/ # Server functions + DB queries
βββ db/ # Schema + migrations
βββ lib/ # Auth, utils
βββ data/ # Subscription templates
Ready-to-use templates with real pricing for quick entry:
Netflix, YouTube Premium, Claude, 1Password, Duolingo, iCloud+, Google One
| Command | Description |
|---|---|
bun run dev |
Start dev server |
bun run build |
Production build |
bun run deploy |
Build + deploy to Cloudflare |
bun run db:generate |
Generate Drizzle migrations |
bun run db:migrate |
Apply migrations (local) |
bun run db:migrate:prod |
Apply migrations (production) |
bun run test |
Run tests |
- All server functions require authentication
- Row-level authorization β users only see their own data
- Zod runtime validation on every input
- CSP, X-Content-Type-Options, and Referrer-Policy headers
- Secrets stored via Cloudflare encrypted secrets, not in code
- Parameterized queries via Drizzle ORM β no SQL injection
Built with care by @phuongphung and Claude.