Showcase: Invoice Studio — an invoicing and e‑invoice widget for Grist by Anupress

Hello everyone :waving_hand:

Advanced Charts has an invoice block that prints one row as a document. People kept asking it for things a block has no business doing, so I pulled it out and spent the summer on it properly. Invoice Studio — a free, open‑source widget that turns the tables you already keep into invoices, quotes, receipts and statements, and gets them sent.

Live demo (no install, no Grist needed):

That one is a builder. Swap construction for restaurant, legal, saas, nonprofit or any of the other trades and you get that whole sample business, wording and numbering and tax settings included. All fourteen side by side.

Use it in Grist → add a Custom widget, paste this URL, set Access to Full document access:
https://anupress.github.io/grist-invoice-studio/

What it does

  • Reads four tables — clients, products, invoices, line items — and works out which is which from your column names. Grist’s own Invoicing template needs no setup at all. If your names are unusual you point it at the right table and column once, in the Data drawer, and a client column called Kunde is then perfectly fine.
  • Eight document kinds out of one table. Invoice, proforma, quote, receipt, credit note, statement, delivery note, packing slip. Each behaves as itself: a quote carries a valid‑until date and no bank details, so nobody can pay it by accident.
  • Tax by country — one rate or a rate table, the EU reverse charge from the two addresses and the VAT number, the §19 UStG sentence and its equivalents, CGST/SGST for India.
  • The client’s language, set once on their record. A French client gets a Facture, a German one a Rechnung, and nobody picks per invoice. Eight languages.
  • The PDF writer is mine, not a library’s. Font subsets go in only when a page actually needs them, so a plain invoice is about 6 KB. Payment QR codes as well: EPC/SEPA, UPI, or your own link. Scripts the embedded font doesn’t cover, Chinese and Arabic and Devanagari, still come out as boxes. That one is on me.
  • E‑invoices — Factur‑X, UBL and CII, on EN 16931, XRechnung 3.0 or Peppol BIS 3.0. This was the part I was least sure of, so every output now goes through the official KoSIT validator, Peppol’s own Schematron and Mustang before a release. All three accept them. In the widget, a check before each send says what the profile is still missing.
  • The month after the invoice. Raise the same document again for next month, add a line of interest for the days overdue, or draw up a statement of everything a client still owes, oldest first.

Sending

It can’t send the email itself. A web page has no mail server. So it writes the message and hands it on four ways: your mail client, a formatted copy with the invoice laid out underneath, an Outbox table for a Grist webhook to deliver, or a POST to an endpoint you run. Only the last one leaves the browser, and it goes to a URL you typed in.

Privacy

No ANUPRESS server, so there is nowhere for anything to go. It does want full document access, which I would hesitate over myself, so here is all of it. It reads four tables at once, and below full access Grist won’t list a document’s tables at all, which makes a document full of invoices look exactly like an empty one. It writes invoice and line rows when you save, adds a column when a field has nowhere to live (a status, a paid date, a client email), stores a catalogue picture as an attachment, keeps its own settings, and writes Outbox rows if you use that route. It never renames or removes anything. I would still try it on a copy first.

Guide and repo

I wrote the whole thing up, every screen and setting, with CSV files carrying the right headers for bringing your clients and products over from a spreadsheet or another tool. Grist Invoice Widget: 100% Free Invoices & E-Invoices - ANUPRESS

Source: GitHub - anupress/grist-invoice-studio: Grist custom widget: invoices, quotes, receipts, credit notes, statements and e-invoices (XRechnung, Factur-X, UBL) from the tables you already keep. PDF, payment QR codes, 8 languages, tax by country. Runs in the browser, no server. Free, MIT. · GitHub (MIT). Self‑hosted Grist can list both ANUPRESS widgets in the Custom widget picker with nothing to paste: set GRIST_WIDGET_LIST_URL to https://anupress.github.io/grist-invoice-studio/manifest.json.

What I’d love feedback on

  1. Point it at a document that already has invoices in it. Did it read your tables, or did you have to describe them in the Data drawer?
  2. Which e‑invoice profile do your customers actually ask you for, if any yet?
  3. Would you use the Outbox and webhook route? If anyone would, I’ll write it up as a proper recipe rather than the paragraph it gets now.
  4. Which trade is missing?

And one for anyone from Grist Labs: the gallery README doesn’t say whether externally hosted widgets can be listed, and every entry in it today lives inside the repository. Would a pull request adding a folder with the built widget be the way in, or is an external URL fine?

Thanks for taking a look — happy to answer questions or take PRs.
— Anupress Team

2 Likes

This is really awesome.

I have a side-request: could you share your workflow to get this functionality implemented?

It seems you’ve used AI, but don’t want to assume :slight_smile:

Would be good to know for replicability!

thanks!

1 Like

Hello @Nico_Pace,

Thanks, glad you liked it.

Yes, I have used AI.

I do the research and brainstorming first. Once I’m happy with my initial draft, I use AI to write the code fast. Then, after a lot of revisions and testing, AI rewrites my drafts into something postable, and when I finally feel it’s ready, I publish the tutorial post on our website and showcase it here.

If you have any more questions, feel free to ask!

Thanks for your answer.

I guess my follow-up question is in regards of structured prompting, skills, or tools you might be using for this.

I think there is not enough written about this workflow, and the more we share, the more we find the right abstractions and methods to learn together.

Thanks for sharing!!

1 Like

Fair question, and I’ll admit part of it I can’t show: my own notes and sketches after the research, way too messy to post anywhere. Just scribbles while I work out what a real invoice needs by trade and which rules actually apply.

Once that’s sorted in my head, I feed it all to Claude, mostly Opus 4.7 through Claude Code, and keep going back and forth until it actually gets what I’m after. That part is most of the real work, honestly! Once I’m happy with the plan, coding starts phase by phase rather than all at once, so a wrong turn gets caught early instead of after everything’s built on top of it.

The rest is checking rather than trusting. Every e-invoice file goes through the real KoSIT and Peppol validators before I call it valid, and the test suite runs before every release. I hope it helps!

Yesterday I had a realization. I created a local setup with Grist desktop:

I got the API key and pass it on to OpenCode. I have an OpenCode Go subscription (5usd/month).

Asked Muse Spark 1.3 model to connect through local MCP using GitHub - gwhthompson/grist-mcp-server · GitHub and also the Py_grist_api Python library and it is working.

I can prompt the Agent and it creates widgets as well as grist tables and we can talk both in terms of grist structures and in terms of widget structures is pretty amazing and pretty straightforward.

It is also EXTREMELY quick… I can iterate in 1min iterations with full widgets created. Prototypes of course… but a clear base to explore interaction options before settling in the widgets that are needed.

2 Likes