Some software ideas become complicated because the problem is complicated.
Others become complicated because the developer keeps adding things.
Khata forced me to confront the second category.
The idea was simple: a personal, offline financial tracking application where I could record transactions, organize accounts, attach receipts, create categories, and understand where money was going.
No bank connection.
No giant backend.
No requirement for every financial provider to integrate with the app.
Just a private tool for recording reality.
The temptation to connect everything
When you build a finance application, it is easy to imagine ambitious features:
- bank synchronization
- automatic transaction imports
- investment APIs
- payment integrations
- cloud dashboards
- multi-device sync
Those features sound useful.
They also introduce authentication, permissions, security, provider dependencies, API limits, synchronization conflicts, and privacy concerns.
For Khata, I deliberately wanted a different philosophy:
The user's financial record should not need a remote service just to exist.
That pushed the architecture toward local storage and an offline-first experience.
The form taught me about friction
A transaction does not need twenty fields.
The core information is straightforward:
- amount
- account
- note
- category
- optional receipt
The time should be captured automatically rather than forcing the user to fill it in.
That sounds like a tiny UX decision, but it represents a larger principle: every field has a cost.
If recording an expense takes too long, people stop recording expenses.
The best finance tracker is not the one with the most analytics.
It is the one you actually keep using.
Offline-first changed the product mindset
When data lives locally, the application has to take local state seriously.
There is no server to rescue a badly designed data model.
The app needs predictable storage, migration thinking, validation, and clear backup/export strategies.
It also changes the privacy model.
A local application can avoid sending the entire transaction history to a remote database by default.
That does not automatically make it perfectly secure, but it changes the amount of data exposed by the architecture.
AI should be an assistant, not the ledger
I wanted AI features in Khata, but I did not want the AI to become the source of truth.
The transaction record should remain structured data.
AI can help interpret it:
- categorize transactions
- identify spending patterns
- explain trends
- generate summaries
The AI result can be cached locally.
This separation matters.
If an AI response disappears, the financial record should still be intact.
That is a useful architecture pattern for many AI applications:
Keep deterministic data authoritative. Let AI add interpretation.
The product lesson
Khata also made me question the idea that every project needs a backend.
Sometimes the best architecture is the smallest architecture that satisfies the requirements.
A local-first application can be faster to develop, easier to reason about, cheaper to operate, and more private by default.
Of course, it comes with trade-offs.
Multi-device synchronization becomes harder.
Recovery and backup become important.
Storage migrations need attention.
But those are honest trade-offs.
What I learned
Khata taught me that good product design is often subtraction.
Remove the unnecessary integration.
Remove the unnecessary form field.
Remove the unnecessary server dependency.
Remove the feature that sounds impressive but does not improve the core workflow.
The result can be more useful precisely because it does less.
That is a lesson I want to carry into my larger projects.
Not every problem needs a distributed system.
Not every app needs AI everywhere.
Not every user needs another dashboard.
Sometimes people just want to open an app, record what happened, and trust that their data is still there tomorrow.