The idea
A command-line tool for developers and freelancers who want to write invoices the same way they write everything else: in a text editor. You create a .md file with YAML frontmatter describing the client, line items, and payment terms. Running invoice build invoice.md produces a clean, numbered PDF in the same directory. Sender info lives in a one-time config file so you never re-enter your address.
Why build this
Freelance developers typically invoice with Word, a Google Doc they cloned once, or a SaaS tool that charges a monthly fee to send twelve invoices a year. All of these involve clicking through a UI, filling in the same fields again, and exporting or printing to PDF manually.
A Markdown-first workflow fits how developers already work: the file is trackable in git, diffable, template-able, and scriptable. Since freelancers often repeat the same line items (hourly rate, fixed fee), a simple YAML schema handles 95% of real invoices without any GUI at all. The tooling to do this — gray-matter, a Handlebars template, Puppeteer — is mature and freely available. Nobody has assembled it into a focused CLI.
Stack sketch
- Runtime: Node.js, distributed as a single
npx-runnable package - Frontmatter parsing:
gray-matter - HTML templating: Handlebars — one default template bundled, user can override with
--template - PDF rendering: Puppeteer (headless Chromium); optional fallback to
wkhtmltopdffor users who want a smaller install - Config:
~/.config/invoicecli/config.tomlfor sender name, address, bank details, default currency - Invoice numbering: auto-incremented counter stored in config directory, overridable in frontmatter
Scope for v1
In:
- invoice build <file.md> → outputs <invoice-number>.pdf next to the source file
- Frontmatter fields: client (name + address block), invoice_number (auto if omitted), date, due (date or net-30 shorthand), currency, items (array of {description, qty, rate})
- Tax line as an optional percentage field (tax: 0.20)
- One bundled HTML/CSS template — readable, professional, print-safe
- Subtotal, tax, and total calculated automatically
- invoice init command to write the initial config file
Out of v1: - Multiple templates - Email sending - Recurring invoices - Time-tracking integration - Payment links
Where it could go
The natural next step is invoice send <file.md> — render the PDF and email it to the client address in the frontmatter using SMTP credentials from config. This keeps the tool self-contained and avoids any third-party dependency for delivery. After that, payment links become interesting: embed a Stripe checkout URL in the PDF footer, generated at build time using the Stripe CLI or a small API call, so the client can pay by clicking a link in the PDF rather than doing a bank transfer manually.
A second expansion is a small git-friendly invoice log — a ledger.csv that invoice build appends to on each run, recording invoice number, client, amount, and date. That gives you a paper trail and makes it trivial to sum outstanding invoices with a one-liner.
Watch out for
Puppeteer bundles Chromium (~150 MB), which makes the install heavy for a CLI tool. Offer --renderer=wkhtmltopdf as an alternative for users who already have it installed, and document it prominently so they don't feel forced into the larger download.