I wanted to write this one more like a real project checkpoint than a polished post.
The Habit Tracker has been one of those projects where it is very easy to get distracted by architecture, backend setup, auth flows, deployment, and all the usual infrastructure work before the core product even feels good to use.
I have been trying not to do that here. The goal from the start was pretty simple: make a habit app I would actually want to use, make sure journaling fits naturally into it, and only then keep hardening the stack around that.
Another reason I picked this project is that parts of the stack were not familiar to me. I wanted something real enough to force me to learn instead of just reading docs or following small tutorials. Building the app while figuring out Angular, the Go backend shape, and how those pieces should meet has probably been the most useful part of the whole thing.
What I am building
At a high level, this is a full-stack habit tracker with a journaling layer built into the daily workflow.
- Frontend: Angular application focused on habit completion and daily journaling
- Backend: Go API scaffold designed for authenticated, database-backed persistence
- Repo strategy: decoupled frontend and backend in a monorepo so both can evolve independently
The basic workflow I am aiming for is:
- selecting a month
- checking habits per day
- writing short daily journal entries
- seeing progress over time
Nothing especially flashy. The whole point is for it to feel lightweight enough to use every day.
It has also been a good excuse to learn by doing. I tend to understand new tools better when I have to make actual product decisions with them instead of building another throwaway demo.
Why I started with the frontend
The biggest call early on was to not wait for the backend to be fully real before building the main product flow.
That helped in a few ways right away:
- I could test the habit and journaling flow immediately instead of designing API contracts in a vacuum
- Local browser persistence let me keep moving without dealing with deployment or infrastructure up front
- The frontend state and screens started revealing what the API actually needs to support
- I could get comfortable with an unfamiliar stack by building visible features first instead of hiding in setup work
So the rough strategy became: make the UX feel real first, then make the backend catch up to it.
Where the project is right now
Right now it feels like a strong shell with the right seams in place, but not a finished full-stack app yet.
What is already working
- Vertical-slice frontend architecture is in place
- Dashboard flow is functional
- Month-based habit matrix is interactive
- Daily journaling UX is implemented
- Local persistence keeps data across browser restarts
- Health check path from frontend to backend exists
- Backend routes, middleware, and feature boundaries are scaffolded
What is still unfinished
- Backend business repositories still return not-implemented placeholders
- Full auth lifecycle is not wired end-to-end (register/login/me token flow)
- Frontend still relies mostly on local state as source of truth
- Production hardening items remain (smoke tests, observability, rate limiting, deployment settings)
I do not really see that list as accidental mess. It is more that I have been choosing what to finish later on purpose instead of pretending everything needs to be production-ready on day one.
Decisions I already feel good about
A few decisions have made the project easier to reason about, even though the implementation is still incomplete.
1. Vertical slices on the frontend
Grouping the frontend by feature instead of file type has already made the app easier to navigate. Auth stays with auth, dashboard stays with dashboard, and I do not have to bounce across a bunch of global folders to understand one feature.
2. Keeping the Go backend layers explicit
The handler to service to repository split is probably the most useful backend decision so far. It makes the placeholders obvious, but it also means I know exactly where the real Postgres-backed code is supposed to land.
3. Putting middleware in early
Even though the backend is not fully wired up, having logging, request validation patterns, auth middleware, and protected route groups in place already makes the shape of the API feel more real.
4. Using local persistence as a bridge
Local storage is not the destination, but it has been useful. It let me test whether the app flow actually works before forcing everything through the API.
5. Being careful about browser-only behavior
Some frontend integration work already had to account for SSR and browser-only behavior, which is the kind of thing that is easy to ignore until deployment starts breaking.
Why I am building it this way
A lot of side projects die in the middle.
They get too complicated to keep moving on, but they never become complete enough to feel real either. I am trying to avoid that by working in this order:
- prove UX
- establish architecture seams
- migrate persistence
- harden for production
That order just feels more honest for this project. I would rather have something usable with known gaps than a huge amount of backend code supporting a product flow that still feels wrong.
What I need to do next
The next big step is making the backend real enough that the frontend can stop treating local state as the main source of truth.
- Implement real auth issuing and verification flow
- Replace placeholder repositories with Postgres-backed implementations
- Move dashboard data writes and reads from local storage to API
- Add guards, interceptors, and protected route behavior
- Add smoke coverage for auth, habits, journal, and health paths
- Close go-live checklist items for observability and deployment
Once those pieces are in place, the project stops being mostly a frontend-first prototype and starts feeling like an actual production path.
Current takeaway
The Habit Tracker is in a good place, but it is definitely still in-between stages.
The product flow is real enough to use and evaluate, the architecture is clear enough that I know where the missing work belongs, and the next milestones are obvious. That is honestly the main thing I wanted at this stage.