A free, open-source invoice editor. Click any line and write, then download a print-ready PDF.
No account, no server, and your invoice never leaves your browser.
Try it at trybilly.tech · Features · Run it locally · Contributing
- You edit the invoice itself. There are no forms or dialogs. Click the company name, a line item or the due date and type.
- The PDF matches the screen. The editor, the preview and the export all render the same page, so what you see is what you download.
- Nothing to sign up for, nothing uploaded. There are no accounts, no backend and no database. Your draft is saved in your browser's local storage.
Editing
- Click-to-edit fields right on the document, with autosave to your browser
- Undo and redo, a ⌘K command palette and keyboard shortcuts
- Multi-page invoices
- An editor that works on a phone
Look
- Ten templates: Clean, Modern Green, Minimal Teal, Corporate Blue, Mono Classic, Mono Elegant, Studio, Ledger, Receipt and Letterhead
- An extra Early Bird template for the people who joined the waitlist
- Logo and digital stamp upload
Money
- Ten currencies: INR, USD, EUR, GBP, JPY, AUD, CAD, SGD, AED and SAR
- Tax and discount, payment terms (on receipt, Net 7, 15 or 30), bank details, PO numbers, notes and terms
Made for India as well
- GSTIN, HSN and SAC codes, CGST, SGST and IGST lines, and reverse charge
- Quick presets for freelancers, GST vendors, agencies and consultants that switch on the fields each one needs
Export
- A print-ready PDF generated in the browser
browser: / (landing) and /editor → InvoicePage → localStorage
│
canvas, preview and PDF all render this one page
apps/web/components/invoice/invoice-page.tsxis the single layout used for the canvas, the preview and the PDF, so the three cannot drift apart.- The PDF is made in the browser from that same page (
html-to-imageandjsPDF). packages/invoice-coreholds the pure TypeScript domain: types, totals, templates, themes, currencies and presets. It has no React in it and it is the only part with unit tests.- The site is a Next.js static export. There are no route handlers, server actions or middleware.
You need Bun (the version is pinned in packageManager in package.json).
bun install # install every workspace
bun run dev # start the app on http://localhost:3000
bun run build # static production build into apps/web/out
bun run lint # lintChecks for the domain package:
cd packages/invoice-core
bun test # unit tests
bunx tsc --noEmit # typecheckA Turborepo on Bun workspaces:
billy/
├─ apps/
│ └─ web/ # the Next.js app: landing page, editor and early birds wall
│ ├─ app/ # routes: /, /editor, /early-birds
│ ├─ components/ # invoice/ (editor), landing/, founders/, ui/, icons/
│ └─ lib/ # PDF export, storage, early bird helpers
├─ packages/
│ ├─ invoice-core/ # @billy/invoice-core: types, totals, templates, currencies, presets
│ ├─ design/ # @billy/design: design tokens
│ └─ typescript-config/ # shared tsconfig base
├─ scripts/founders/ # launch-day CLIs for early bird numbers and unlock links
├─ docs/ # project documentation
├─ DESIGN.md # the design spec of record
├─ wrangler.jsonc # Cloudflare Worker config: serves the site on trybilly.tech
└─ vercel.json # Vercel build settings and security headers
The app is a static export (output: 'export' in apps/web/next.config.ts), deployed on Cloudflare Workers from main. wrangler.jsonc routes trybilly.tech and www.trybilly.tech to the billy Worker, which serves apps/web/out; Cloudflare Workers Builds builds and deploys every push to main. Vercel still builds preview deployments for pull requests, with vercel.json holding those settings. DNS is on Cloudflare.
- Install command:
bun install - Build command:
bun run build - Output directory:
apps/web/out - Environment:
NEXT_PUBLIC_POSTHOG_PROJECT_TOKENfor analytics. It is read at build time, and analytics stay off without it.
Production security headers come from apps/web/public/_headers, which Cloudflare reads when serving the export; vercel.json keeps the same set on previews. Deploy steps, the apex redirect and rollback live in docs/deploy.md.
Contributions are welcome. billy is small, so the process is light. The short version is below, and CONTRIBUTING.md has the rest.
- Open an issue first for anything bigger than a small fix, so we can agree on the approach before you write code. Typos and obvious bugs can go straight to a pull request.
- Branch from
mainand keep each pull request to one change. - Before you push, check that
bun run buildpasses and thatbun run lintreports nothing new. - For anything visible, include before and after screenshots at desktop and phone widths.
- Match the code around your change. The UI follows
DESIGN.md, and user-facing copy uses plain punctuation, so no em-dashes. - Using an AI coding agent? Read
AGENTS.mdfirst.
By contributing, you agree that your work is licensed under the MIT license.
If billy saves you time, a star on GitHub helps other people find it.
MIT. Bundled third-party files keep their own licenses, listed in THIRD_PARTY_NOTICES.md.