Context: Most personal finance apps are overkill or locked behind subscriptions. I wanted a single tool that tracks expenses, income, subscriptions, and estimated taxes — and that I'd actually use myself.
Challenges: Architecting a clean frontend/backend split in Streamlit was the main design hurdle. I built separate repos for the UI layer and the data layer so that the backend could be reused independently of the Streamlit interface. Deploying to Streamlit Cloud also required careful dependency management.
Result: A deployed, fully functional multi-mode finance tracker with a CLI and a Streamlit web dashboard — six pages covering expenses, income, subscriptions, and tax estimates. Started as a school submission; evolved into a production-ready app.
How the App is Structured
The Finance Kit — Architecture ════════════════════════════════ ┌──────────────────────────────────────────────────────┐ │ run.py │ │ (entry point) │ │ questionary prompt → CLI or Web UI? │ └──────────────────────┬───────────────────────────────┘ │ ┌──────────┴──────────┐ ▼ ▼ ┌────────────────┐ ┌──────────────────────────┐ │ CLI Mode │ │ Web UI Mode │ │ cli/cli_app.py │ │ streamlit run │ │ │ │ app/Dashboard.py │ └───────┬────────┘ └────────────┬─────────────┘ │ │ │ ┌────────────┴────────────┐ │ ▼ ▼ │ Dashboard.py pages/ (6 pages) │ Add / Edit / Delete Material │ View Expenses │ View Income │ View Subscriptions │ └─────────────────┬───────────────────────┘ ▼ ┌──────────────────┐ │ core_stuff.py │ ← single data layer │ reads / writes │ shared by CLI + UI │ data.json │ └──────────────────┘ Both modes share the same backend — swapping the UI never touches the data layer.
Data Flow — Adding an Expense ═══════════════════════════════ User fills form → Streamlit session_state holds draft │ ▼ on submit core_stuff.py: load_data() │ read data.json → dict ▼ append new entry to dict["expenses"] │ ▼ core_stuff.py: save_data() │ write dict → data.json ▼ Streamlit reruns → updated View Expenses page Tax estimate → sum(income) × tax_rate(bracket) Budget check → sum(expenses_this_month) > budget_limit? All reads and writes go through core_stuff.py — the UI never touches data.json directly.
In Action
Live Streamlit dashboard with expense, income, subscription, and forecast sectionsExpense entry workflow in the live Streamlit app
Dev Notes
Problems Solved
Most finance apps are overkill or locked behind subscriptions. I needed a single tool that tracked expenses, income, subscriptions, and estimated taxes — and that I'd actually use daily without paying a monthly fee.
Errors & Fixes
Streamlit Cloud deployment failed because transitive dependencies weren't pinned — fixed by running pip freeze and committing every version to requirements.txt. Backend API calls from the frontend triggered CORS errors until I added explicit response headers to all endpoints.
What I Learned
How to architect a clean Streamlit frontend/backend split so the data layer can be reused outside the UI. Streamlit Cloud's build pipeline, the importance of dependency pinning in production, and how multi-page Streamlit apps are structured.