Too Many Todos, Not Enough Time

August 19, 2025

By Anthony Alcala

What is the minimum viable product?

After 3 years of hosting my own billing solution and playing around with different features I have decided to put invoicing capabilities at the heart Varcaliber. This decision is based on the assumption that there is a demand for a self-hosted solution and that the ability to create and deliver invoices and receive payments is enough to gain initial traction.

I will focus my time and energy into making the invoicing aspect good enough to encourage other freelance software developers to start using Varcaliber to manage their client billing.

What makes a good self-hosted invoicing solution is to be determined. I have already implemented some of my ideas. Although I have already built features for tracking hours and generating reports which I use for my own clients, these are features that I don’t think are worth dedicating more time to until I have seen that they are valuable to other people.

Core Features

  • Creating and delivering invoices
  • Receiving payments

Making some features experimental

Knowing what is essential, all other features can be inferred as non-essential. Since my time is limited, I must focus on the essential. Every minute I spend developing things that don’t matter is a minute I don’t have to develop the things that do matter. In order to deliver the most amount of value in the shortest amount of time, I have made other features opt-in only.

Now I can focus on making the core features more reliable and ready for early adopters, while also allowing myself to continue to use the other features for my own business.

So far the experimental features include:

  • Issues
  • Time Tracking
  • Reports
  • Organization Stats

These features are:

  1. Decoupled from the essential features
  2. Disabled by default (inaccessible and invisible)
  3. Treated as second-class (meaning they will have fewer tests and less stringent coding standards)

These experimental features have the potential to become core features, but for now they will remain on the sidelines.

How experimental features are enabled

I wanted to implement the simplest version of this functionality as I could so I decided to tie this in with the existing settings management system that I had already built.

The settings system merges default config values that are defined in the application config file (app.php) with values stored in the settings table as key/value pairs. If there are is no matching record in the settings table for a specific setting, the default value is used.

Each feature flag has its own setting and each setting is set to false by default.

Settings can be updated by the admin user by visiting the Settings page. To enable a feature, the user just has to change the feature flag’s value from “false” to “true”. Once this is done, the corresponding navigation items will become visible and routes will become accessible.

Why does this matter?

I’ve learned from past projects that it’s best to do one thing and do it well. Too many times I have seem that the opposite of this is done. I can think of many examples where a product is filled with half-baked features and the user doesn’t know exactly what they are supposed to do with them or why they matter.

Some benefits of labeling non-essential features as experimental and disabling them by default include:

  1. Helping the user understand why this software matters to them by giving them clear and immediate value without distraction
  2. Allowing myself to consolidate my efforts and apply more stringent standards for testing and UX on features that will have the greatest impact
  3. Giving myself and others the mechanism for testing out new features at the earliest stages before committing more time to them