Building in Public

Lessons from Dogfooding Your Own Product

4 min read

Over the past year and a half, I've been building totalHOA, a multi-tenant SaaS platform for community associations. After nearly a decade leading web engineering at Cardinal Financial, I'm now navigating a career transition and building totalHOA every chance I get.

The platform includes operational tools for HOA governance, but the piece I want to talk about here is the web engine underneath: a modular block system, dynamic page builder, tenant-aware architecture, and a flexible design layer built on Laravel, Livewire, Tailwind, and Alpine.

As I started planning a new portfolio site, I realized something. The web engine I'd built, including the block system, page builder, and theming layer, was not HOA-specific at all. It was a general-purpose content platform that happened to live inside an HOA product. That meant I could battle-test it on a completely different real-world use case without pretending the fit was something it wasn't.

So rather than reaching for an off-the-shelf CMS, I decided to build the portfolio inside totalHOA itself. The site you're reading right now is that portfolio, built entirely on the same block system, page builder, and theming layer described in this post. It became both a showcase and a stress test, a live example of the engine powering a use case it was never originally designed for. That is where the interesting lessons live.

The block editor was not part of the original plan

When I started totalHOA, I assumed HOA websites would be fairly static: a homepage, a few informational pages, maybe a document library. I could have hardcoded page templates or built a rigid layout system. That would have shipped faster.

But as I worked more closely with what communities actually need, a digital presence that reflects their identity without requiring constant developer involvement, I realized the real problem was flexibility without chaos. I needed a structured system of composable blocks that gives non-technical admins creative freedom while keeping the underlying architecture disciplined and extensible.

The lesson is that some of your most valuable features are the ones you did not plan. The block editor started as a nice-to-have and became one of totalHOA's most architecturally interesting systems, not because I specced it that way, but because I listened to the problem long enough for the real need to surface.

Dogfooding breaks your assumptions about your own abstractions

Building an HOA community site and building a developer portfolio are fundamentally different use cases. The moment I started designing my own portfolio inside totalHOA, I found the edges of every assumption I had baked into the block system.

Layouts I thought were flexible enough turned out to be opinionated toward community content patterns. The theming layer handled tenant branding well but resisted the kind of expressive, single-purpose design a portfolio demands. Data structures that made sense for articles and events did not map cleanly to case studies and project showcases.

None of these were bugs. They were design assumptions that only became visible when I pushed the system outside its original context. The lesson is that dogfooding only works if you use your product in ways that make it uncomfortable. Building a second community site would have confirmed my biases. Building something fundamentally different exposed them.

Purpose-built does not mean single-purpose

The instinct when building for a specific market is to optimize everything for that market. But overfitting to one use case creates brittleness. The portfolio exercise forced me to refactor several block components to be more genuinely composable. Those changes made the system better for HOA sites too, not just for my portfolio.

The takeaway is that designing for one hard adjacent use case makes your core use case more resilient. If the block framework can power both a 1,961-home community site and a personal portfolio without forking the codebase, the abstraction layer is working.