danherbert.io logo
dev-diary general

The importance of dogfooding

Having released Elide recently, I've been keen to put it through its paces beyond the scope of a demo site, unit testing, and this personal site.

This week I started a fresh project which includes more of the common pieces of dynamic functionality, including (but not limited to):

  • Registration and auth processes
  • Dynamic forms (with file uploads)
  • Paginated data tables with sorting and filtering
  • File exports

Similar to the rebuild of this personal site, I was very happy with how quickly I was able to get things up and going - even with no starter kit and adding auth/etc to a fresh project.

As I got a bit deeper into the project I came across a problem...

Discovering the issue

While building out a UI to display a collection of transaction data, I hit a rendering issue with nested Partials - they appeared empty despite being declared.

This particular page contains a few things:

  • The page itself (an Elide Partial)
    • A summary table (also a Partial)
    • A dynamic data table (also a Partial)

The idea here is that if someone filters the data table, or changes the data table's page number, only the data table Partial is updated, not the Partial for the whole page.

Elide could already handle this, however nested Partials had a problem - at initial full-page render time ancestor Partials weren't aware of the rendered state of descendant Partials. This meant that any nested Partials ended up being empty in full page responses, even if they were actually declared and had content.

A solution, but not the "right" solution

This could be easily solved without updating Elide:

One workaround was to create a separate route (e.g. /get-the-tables) that returns the summary and data table, then use hx-get="/get-the-tables" and hx-trigger="load" to fetch and swap in those components on page load. This worked, but felt clunky.

This is a viable but philosophically misaligned solution.

Approaches like this require more coordination between routes and components, and also increase complexity. This moves away from Elide's intent.

I want Elide to be as smooth to use as Intertia + React/Vue. It felt like nested Partials should just work. It's something you would intuitively "just do" when setting up more complex UIs.

The real solution

The solution was simple in the end: as each Partial is rendered, share the result with Laravel's View factory.

Elide was already sharing Partials, but only after all were rendered, just before the main component to be rendered and returned to the browser.

Note

If you're curious about the code, you can check the diff on Github.

This really pushes things in the direction I want. I can now have a single route to serve the entire page with deeply nested Partials, and it also can respond with only the required sub Partials. This makes the frontend updates more targeted, leaner to transfer over the network, and less likely bounce the page around with larger swaps.

This small shift means Partials now behave intuitively in both full and partial responses - a major quality-of-life improvement for users.

Dogfooding is incredibly valuable

Dogfooding your own things is something I've always felt provides immense value.

When dogfooding, you:

  • Validate that your tool solves real problems
  • Catch bugs and UX issues early
  • Deepen your intuition about how it performs in real-world use
  • Build empathy for your users
  • Increase your own confidence in the product

One of my favourite examples of how dogfooding can guide a product's ongoing development and value is to look at Epic Game's Unreal Engine and Unity Technology's Unity Engine.

Both are great engines, but there is a key difference: Epic have been making and selling games with their technology for more than 25 years, whereas Unity only started very recently with the game Survival Kids.

Unity's tools often feel like they were built by engineers who don't ship games themselves - whereas Unreal's workflows reflect lived experience in game production.

Closing / TL;DR

Use your own tools. Feel their pain points. Fix them. Improve faster.

Your users (and you!) will thank you. 🙏