← All posts

invox: invoicing that lives in a container

A personal invoice generator with a SQLite file behind it and PDF export. My banking details live in the database, so the code can be public.

I needed to send invoices. The choices were a spreadsheet, which produces ugly PDFs and no history, or an invoicing service that wanted to run my whole practice for a monthly fee. I wanted the third option: a small app that makes an invoice, remembers it, and exports a PDF that looks right.

invox is that. You fill in the invoice in the browser, it lands in a SQLite file, and the PDF you download is the invoice you see on screen. The interface is React and TypeScript, the API is Hono, and pdf-lib draws the export.

The repo is the tool, the database is the letterhead

The lines that identify me on an invoice, the ACH payment details, and the footer text are all edited on a Settings page and stored in the runtime database. None of it is in the repository. That split is deliberate. I can share the code, and anyone can run it, without either of us leaking bank details into git history.

Running it

Continuous integration builds an image on every push to main, tagged latest and with the commit hash. The data directory is one SQLite file, so backing up is copying a file and rolling back is pinning an older tag. For something that handles money, I wanted both of those to be boring.