Because tracking subscriptions shouldn't be a subscription to stress
Hey there! This is AkwaFlow — my take on a subscription management app that actually makes sense. You know that feeling when you're paying for Netflix, Spotify, YouTube Premium, and like 10 other services, but you have no idea how much you're actually spending? Yeah, me too. So I built this.
|
|
AkwaFlow helps you keep track of all your subscriptions and expenses in one place. It's not just another boring expense tracker — it's got some cool features that make it actually useful:
- Beautiful Analytics — See your spending patterns with clean charts and graphs
- Expense Tracking — Track one-time expenses alongside your subscriptions
- Smart Categories — Organize your subscriptions and expenses however makes sense to you
- Telegram Bot — Manage everything right from Telegram (because who opens apps anymore?)
- Smart Icons — Automatically fetches service logos (Netflix, Spotify, etc.) or uses clean letter icons
- Multi-Currency — Supports RUB, USD, WON, KZT and more
- Mobile-First — Works great on your phone, tablet, or desktop
You'll need:
- Node.js (v18 or higher)
- A Firebase project
- A Telegram bot token (if you want the bot feature)
See PRIVACY_POLICY.md.
# Clone the repo
git clone <your-repo-url>
cd AkwaFlow
# Install dependencies
npm install
# Set up the bot (optional)
cd bot
npm install- Create a Firebase project and get your config
- Set up environment variables (create
.envfile locally):VITE_FIREBASE_API_KEY=your_api_key VITE_FIREBASE_AUTH_DOMAIN=your_project.firebaseapp.com VITE_FIREBASE_PROJECT_ID=your_project_id VITE_FIREBASE_STORAGE_BUCKET=your_project.firebasestorage.app VITE_FIREBASE_MESSAGING_SENDER_ID=your_sender_id VITE_FIREBASE_APP_ID=your_app_id
- Set up Firestore rules (check
firestore.rules)
- Copy
bot/service-account.example.jsontobot/service-account.json - Fill in your Firebase service account credentials
- Create a
.envfile in thebot/directory:
TELEGRAM_BOT_TOKEN=your_bot_token_here
WEB_APP_URL=https://your-app-url.com# Start the dev server
npm run dev
# Build for production
npm run build
# Run the bot (in bot/ directory)
cd bot
node index.js
# Run bot self-checks
npm run selftest
npm run selftest:dialogYour main hub for managing subscriptions. You get three summary cards showing your monthly subscription total, how many subscriptions you have, and when the next payment is due. Below that, a clean list of all your subscriptions with their icons, billing cycles, and costs.
I designed the cards to be simple but not boring — rounded corners, subtle decorative circles inside, and smooth hover effects. Purple theme for subscriptions because it feels premium.
Added this feature because sometimes you need to track one-time expenses, not just recurring subscriptions. You can track expenses by category (same categories as subscriptions), add dates, and see monthly totals.
The design matches the subscriptions page — same rounded cards, but with orange theme to differentiate from subscriptions. Three summary cards show this month's expenses, total count, and previous month for comparison.
This is where things get interesting. You get six summary cards (three for monthly, three for yearly) showing subscriptions, expenses, and totals. Below that, pie charts break down your spending by category for both subscriptions and expenses. And there's a bar chart comparing subscriptions vs expenses month by month.
All charts are responsive and look good on mobile. I used Recharts because it's simple and works well with React.
You can organize everything however you want. Create custom categories with your own colors. Each category shows how many subscriptions it has and the total cost. When you create a subscription or expense, you just pick the category from a dropdown.
I kept the category management simple — just a name and a color. No complicated hierarchies or tags. Sometimes simple is better.
The icon system works like this: when you add a subscription or expense, the app tries to find a logo for that service. If it's a popular service like Netflix or Spotify, you'll get the actual logo. If not, it just shows the first letter of the name in a colored circle.
I removed the external API calls for icons because they were giving ugly or unclear results. Now it's either a good logo or a clean letter — nothing in between.
The bot uses rule-based parsing for Telegram messages. It now handles a wider range of natural phrasing without switching to a full LLM flow:
- Inline categories such as
Расход 5000₩ такси сегодня категория Транспорт - Voice-like short phrases such as
Netflix 10000₩ 12 числаorКофе 6000вон сегодня - Ambiguous money phrases by asking a short follow-up:
расход,доходorподписка - Interrupting a follow-up with a new intent like
мои расходыorмои подписки
Current limitation: when a message contains only an amount and a title but no clear type, the bot may ask one extra clarifying question before saving.
I built this with modern tools because life's too short for legacy code:
AkwaFlow/
├── src/
│ ├── components/ # React components
│ │ ├── features/ # Feature-specific components
│ │ ├── layout/ # Layout components
│ │ └── ui/ # Reusable UI components
│ ├── context/ # React Context providers
│ ├── pages/ # Page components
│ ├── services/ # API services, Firebase, icon fetching
│ └── lib/ # Utilities
├── bot/ # Telegram bot
└── public/ # Static assets
I wanted this to feel modern but not trendy. Dark theme by default (because my eyes), smooth animations, and a focus on readability.
The latest update added rounded cards with subtle decorative circles inside — not blurred, just clean semi-transparent circles that add depth without being distracting. Purple for subscriptions, orange for expenses. It's a simple color scheme but it works.
No unnecessary complexity. Just what you need, when you need it, presented in a way that doesn't hurt your eyes.
Found a bug? Have an idea? Feel free to open an issue or submit a PR. I'm always open to suggestions and improvements.
This repository uses semantic-release with GitHub Actions.
- Every push to
masterruns the release workflow in.github/workflows/release.yml mainis also supported if the default branch is renamed later- A successful release updates
package.json,package-lock.json, andCHANGELOG.md - The workflow then creates a git tag and a GitHub Release automatically
Release versioning is based on Conventional Commits:
fix: ...-> patch releasefeat: ...-> minor releasefeat!: ...or aBREAKING CHANGE:footer -> major release
Examples:
fix: correct monthly totals rounding
feat: add recurring payment filters
feat!: replace legacy category ids
Run a local verification before merging to the release branch:
git checkout master
git pull
npm install
$env:GITHUB_TOKEN="<github-token>"
npm run release:dry-runNotes:
semantic-releaseneedsGITHUB_TOKENeven for a realistic dry run- The GitHub Action uses Node.js 22
- Only commits that follow Conventional Commits are considered for automatic version bumps
This project is open source and available under the MIT License.
- Icons powered by Clearbit Logo API and Google Favicon API
- Charts by Recharts
- Icons by Lucide
I built this because I needed it. Simple as that. If you find it useful, great! If you have suggestions, even better. If you just want to see how it works, feel free to poke around the code.


