Expense Tracker App using HTML TAILWIND AND VANILLA JS banner

Expense Tracker App using HTML TAILWIND AND VANILLA JS

5 devlogs
10h 46m 37s

A production-ready financial tracking application where users can manage income, track expenses, categorize transactions, and analyze spending with beautiful interactive charts.
NB- all values will appear in dollar

This project uses AI

Used AI to write readme

Demo Repository

Loading README...

Soujanya

#Day5 — UX Refinement, Validation, and Stability

Today I focused on refining the user experience and eliminating friction. I implemented input validation to prevent empty titles and invalid amounts, which significantly improved reliability.

One issue I encountered was inconsistent form behavior after editing transactions. The form wasn’t resetting properly, causing accidental overwrites. I fixed this by explicitly clearing state after each operation.

The transaction list UI also needed improvement. Without structure, it became hard to scan. I adjusted spacing and alignment to make entries readable and actionable.

What failed: I underestimated how small UX flaws (like not clearing inputs) impact usability. The app felt broken even when logic was correct.

Key learning: a project isn’t finished when it works—it’s finished when it feels predictable and stable to the user.

Attachment
0
Soujanya

#Day4 — Persistence + Data Visualization Integration

Today I pushed the app from a simple tracker to something closer to a real tool by combining data persistence (localStorage) with visual analytics (Chart.js).

On the persistence side, the biggest challenge was maintaining consistency between the in-memory state and localStorage. Initially, I wrote to storage in multiple places, which created duplication bugs and unpredictable behavior. I fixed this by centralizing all updates into a single saveAndRender() pipeline. I also had to handle edge cases like empty or corrupted localStorage data—adding safe parsing and fallback logic prevented the app from crashing.

On the visualization side, integrating Chart.js introduced a different class of problems. My first implementation recreated the chart on every update, causing flickering and performance issues. I corrected this by maintaining a persistent chart instance and updating it using .update().

Another issue was incorrect data aggregation—I initially included income in the expense chart, which made insights misleading.

Key learning: persistence and visualization both depend on data integrity. If your data layer is flawed, everything above it—UI, charts, insights—becomes unreliable.

Attachment
0
Soujanya

Expense Tracker building day 2

Today I built the backbone: the transactions array and CRUD operations. I enforced a single source of truth approach, where every UI element depends on the transactions state. This prevented scattered logic and made debugging predictable.

The biggest mistake early on was trying to directly manipulate the DOM after each action. That quickly became messy. I refactored into a render() function that recalculates everything from state.

Editing transactions was trickier than expected. Managing editing state (editingId) introduced edge cases, especially when switching between add and edit modes.

What failed: I initially mixed validation inside rendering logic, which caused unexpected behavior. Separating concerns fixed this.

Key learning: if your state flow is unclear, everything downstream becomes fragile. Clean state architecture is more important than UI polish at this stage.

Attachment
0
Soujanya

Expense Tracker

Today I focused on translating the idea into a concrete UI structure. Instead of jumping into JavaScript, I deliberately started with layout and visual hierarchy. I built the grid system using Tailwind and enforced the brutalist design language: thick borders, no border radius, and high contrast typography. The goal was to make the UI feel intentional, not “template-generated.”

What failed initially was spacing discipline. Brutalism is unforgiving—poor spacing instantly looks broken, not minimal. I had to rework padding and alignment multiple times to get a balanced composition.

I also underestimated how important semantic grouping is. Separating summary, form, chart, and ledger early prevented future chaos.

Key learning: design is not decoration—it defines how your logic will plug into the interface. A weak layout creates technical debt before you even write JavaScript.

Attachment
0