A Claude Code plugin that turns invoicing into a split‑pane editor: visual controls and an HTML/CSS escape hatch on the left, a live, paper‑sized PDF preview on the right. Drive it by hand in the browser, or let Claude fill in the data and export the PDF for you — both work on the same plain files on disk.
- Split‑pane editor — edit on the left, see the rendered invoice on the right, live.
- Three ways to edit — a Data form, Style visual controls, and a Code tab (raw Handlebars HTML + CSS) for full control. The code always wins over the visual controls.
- Claude‑native — Claude and the editor are peers over plain files. Ask Claude to "invoice Acme for 10h at €90" and it writes the workspace JSON; the preview hot‑reloads.
- Pixel‑accurate PDF export — final PDFs are printed by headless Chromium (Playwright), so anything you can do in CSS renders correctly.
- Reusable pieces — a business profile, a styled template, and per‑invoice data are separate, so one style serves every invoice.
- Fail‑loud — every file read is schema‑validated (Zod); errors surface in the UI instead of producing blank or wrong output.
git clone https://github.com/RiggdAI/invoicerig.git
cd invoicerig
npm install
npx playwright install chromium # one-time, for PDF export
npm run editor # builds + serves http://localhost:4317Open http://localhost:4317. The workspace (a sample profile, template, and invoice) is scaffolded automatically on first run.
Export a PDF from the terminal instead:
npm run export -- sample # writes workspace/output/sample.pdf| Data | Style | Code |
|---|---|---|
![]() |
![]() |
![]() |
- Data — invoice number, client, dates, tax rate, a line‑item table (qty × rate → amount), and notes.
- Style — accent color, font, font size, page size (A4/Letter), margin, logo position. Writes the template's
style.json. - Code — the
template.html(Handlebars) andtemplate.cssescape hatch, with debounced save.
This repo ships the invoice skill. Opening Claude Code in this repo discovers
it automatically (via .claude/skills/invoice). Then:
- Type
/invoice, or just ask in natural language — Claude triggers the skill from its description. - "Create an invoice for Beta Corp: 10h design at €90, 5h dev at €110, due in 14 days" → Claude writes
workspace/invoices/<name>.json; a running editor hot‑reloads the preview. - "Make the accent dark green and use A4" → Claude edits the template's
style.json. - "Export the Beta invoice" → Claude runs
npm run export -- betaand returns the PDF path.
To make it installable as a plugin from anywhere, add a .claude-plugin/marketplace.json,
then /plugin marketplace add https://github.com/RiggdAI/invoicerig and
/plugin install invoice-skills@<marketplace>.
Claude and the editor communicate only through these files:
workspace/
profiles/<profile>.json # your business: name, address, email, currency, taxId, logo
templates/<template>/
template.html # Handlebars: {{client.name}}, {{#each totals.lines}}…
template.css # styles (the "code escape hatch")
style.json # visual-control state (accent, font, page size, margins)
invoices/<invoice>.json # { profile, template, number, client, items[], dates, notes, taxRate }
output/<invoice>.pdf # exported result
Notes: taxRate is a decimal fraction (e.g. 0.2 for 20%), currency is an
ISO 4217 code (e.g. "EUR"). Full field reference lives in
skills/invoice/SKILL.md.
┌─────────────┐ reads/writes ┌──────────────────────┐
│ Claude │ ───── files ────▶ │ workspace/ (on disk) │
│ (invoice │ ◀──────────────── │ templates/ invoices/ │
│ skill) │ │ profiles/ output/ │
└─────────────┘ └──────────┬───────────┘
│ watch / read / write
┌──────────▼───────────┐
browser ◀── React UI ─────▶ │ Node backend │
│ - serves the editor │
│ - file watch → WS │
│ - POST /export (PDF) │
└──────────────────────┘
- Shared render core (
src/shared) — Zod schemas + a pure Handlebars renderer that computes line totals and merges base CSS with the template's CSS. - Backend (
src/server) — Express serving the built UI, a chokidar watcher that pushes file changes over WebSocket, save/state endpoints, and Playwright PDF export (also a CLI). - Frontend (
src/frontend) — Vite + React + TypeScript, styled with Tailwind v4 and shadcn/ui; the preview renders the bound HTML in a sandboxed<iframe>.
| Script | Description |
|---|---|
npm run dev |
Vite dev server + backend in watch mode (frontend on :5173, API on :4317) |
npm run build |
Build the frontend to dist/ |
npm run editor |
Build, scaffold the workspace, and serve the editor on :4317 |
npm run export -- <invoice> |
Export an invoice to workspace/output/<invoice>.pdf |
npm test |
Run the Vitest suite (real server, real Chromium, real WebSocket) |
npm run lint |
Run ESLint |
Tests are real integrations — no mocks — including an end‑to‑end scaffold → save → export check that asserts a real PDF is produced.
TypeScript (ESM) · Vite + React 18 · Tailwind v4 + shadcn/ui · Express + ws + chokidar · Handlebars + Zod · Playwright · Vitest.
MIT — see LICENSE.


