Skip to content

I Built My Own Invoicing App (Mostly Because I Needed It)

No invoicing tool matched how I actually work as a fractional CIO, so I built one: a small MVP that grew into time tracking, contractor billing, client portals and reports. Here's what I built, and what building it taught me.

Comment
I Built My Own Invoicing App (Mostly Because I Needed It)

I built a thing, mostly because I needed it.

As a fractional CIO, my work doesn't fit neatly into most invoicing tools. Some clients are on a monthly plan, some buy extra hours, and some projects bring in contractors who bill me at one rate while I bill the client at another. Every tool I tried either ignored half of that or made me work around it.

So instead of forcing a tool to fit, I started with a simple MVP: clients, invoices, payments. Then I built from there.

The dashboard: outstanding invoices, aging, recent payments and top clients

Then curiosity took over

Every feature after the first version came from a real "what would make this clearer or easier?" moment.

  • Time tracking, because most of what I bill starts as hours. Log time against a client, mark it billable or not, and turn approved hours into an invoice in one step.
  • Expenses, including recurring ones, so the numbers show what an engagement really costs, not just what it brings in.
  • Contractor billing with two rates. Each contractor has the rate I pay them and the rate the client pays me. The app tracks both, so the margin on every hour is visible, and I can see at a glance who I owe and what hasn't been invoiced yet.
  • Portals. Clients log in to see and pay their invoices through Stripe. Contractors log in to submit time and see when they've been paid.
  • Reports and metrics: revenue trends, aging, margins, unbilled time and time by client.

Creating an invoice

Logging time against a client, with the rate filled in from the client

Why vanilla PHP

It's built with plain PHP, JavaScript and Bootstrap 5. No framework.

That wasn't the fastest path. I chose it because I wanted clarity and control: a system I understand end to end, where nothing happens that I can't trace. When something breaks, I know where to look. When I want to change something, I'm not fighting someone else's assumptions.

It's also built with the things I'd expect a client's system to have: an audit log, login protection and rate limiting, and a security monitor.

Time reports: hours, value and average rate by client

What building it taught me

This isn't really about the app. It's about how I approach systems:

  1. Start with the smallest thing that works. The first version was deliberately boring, and it was useful from day one.
  2. Let real work drive what comes next. Every feature came from a moment of friction, not a feature list.
  3. Understand what you depend on. Simple tools you fully understand beat clever ones you don't.

It's the same advice I give clients about their own technology. Build simply, expand thoughtfully, and stay close to the work the system is meant to support.

Built out of necessity. Iterated with intent.

Related reading

Curious how it works, or thinking about a similar build for your own business? Get in touch.

Comments

No comments yet - start the conversation.