All articles
Open SourceInvoicingCase Study

Why We Built a Self-Hosted Invoice System with EU Compliance

AI-FTWFebruary 24, 20268 min read

The SaaS Invoicing Problem

Freelancers and small businesses that invoice internationally face a specific set of frustrations. FreshBooks charges $17-55/month. Wave was free until it wasn't. QuickBooks requires a U.S. bank account for full functionality. And none of them give you actual ownership of your data - your invoices, client records, and financial history live on someone else's servers, subject to someone else's pricing changes and terms of service updates.

For businesses operating across borders - especially those invoicing European clients - there's an additional requirement: UBL and PEPPOL compliance. The European Union's e-invoicing standards mandate specific XML formats for business-to-government and increasingly business-to-business transactions. Most SaaS invoicing tools either don't support these formats or charge premium tier prices for the feature.

What We Built

Invio is a self-hosted invoicing platform built on Deno, Hono, and Fresh - with SQLite for zero-configuration storage, Stripe-free PDF generation, and full UBL 2.1 / PEPPOL BIS Billing 3.0 XML export. It runs on a single server (or a $5/month VPS) with no external database dependencies, no subscription fees, and no third-party data sharing.

Full Invoice Lifecycle

Create, edit, preview, publish, and share invoices through a clean web interface. Each invoice can be shared via a unique public URL with a secure token - clients can view and download their invoice without creating an account or logging in. The PDF generation pipeline uses wkhtmltopdf as the primary renderer with pdf-lib as a fallback, producing professional, print-ready documents every time.

Customer and Product Management

A built-in CRM stores client contact details, and a product catalog manages services with SKUs, descriptions, and default pricing. When creating an invoice, you select from existing customers and products - no retyping the same information on every document.

Multi-Currency and International Tax

Invoices can be issued in any currency with configurable tax rates per line item. This isn't a cosmetic currency symbol swap - the system handles proper decimal precision, tax calculations, and totaling for each currency's conventions.

UBL 2.1 and PEPPOL Export

The standout feature for international businesses: one-click XML export in UBL 2.1 and PEPPOL BIS Billing 3.0 formats. These are the mandatory e-invoicing standards for EU public procurement and an increasing number of B2B transactions. Most small businesses either pay an accountant to generate these files or subscribe to enterprise-tier invoicing software. Invio generates them natively.

Security by Architecture

Self-hosting is a security posture, not just a cost savings. Your financial data never leaves your infrastructure. But self-hosted doesn't mean insecure - we implemented defense-in-depth across the entire application.

Authentication uses JWT with PBKDF2-SHA256 password hashing at 100,000 iterations - the same standard used by password managers. Rate limiting blocks brute force attempts at 5 failed logins per 15-minute window. HTTP security headers include HSTS (forcing HTTPS), Content-Security-Policy, X-Frame-Options: DENY (preventing clickjacking), and X-Content-Type-Options. The Docker deployment includes an nginx reverse proxy configuration with TLS termination.

A demo mode with periodic database resets lets prospective users try the full application without affecting production data - a pattern we recommend for any self-hosted tool that needs a public demo.

Why Deno and Fresh

Deno provides built-in TypeScript support, a secure-by-default permissions model (the runtime can't access the filesystem or network without explicit flags), and native SQLite bindings. Fresh is Deno's web framework - Preact-based SSR with zero client-side JavaScript by default, sending interactive "islands" only where needed. The result is a fast, lightweight application that runs on minimal hardware. No node_modules folder. No webpack configuration. No build step for the frontend.

The Business Case for Self-Hosting

For a freelancer sending 20 invoices per month, the math is straightforward. FreshBooks Professional costs $55/month - $660/year. A VPS to run Invio costs $5-10/month - $60-120/year. Over three years, that's roughly $1,600 in savings, with the added benefit of complete data ownership and no risk of price increases or feature removal.

For businesses with EU compliance requirements, the savings are even more significant. Enterprise invoicing tiers that include UBL/PEPPOL export typically start at $100+/month. Invio includes it at no marginal cost.

Open Source and Extensible

Invio is fully open source. The codebase is clean, well-structured, and documented - built for other developers to fork, extend, and customize. Need recurring invoices? Add a cron job. Need Stripe payment links embedded in invoices? Add a webhook handler. The architecture is intentionally simple so that customization doesn't require understanding a complex plugin system.

If your business needs a custom invoicing workflow - whether it's multi-currency, international compliance, or integration with your existing systems - a 25-minute consultation can help scope out whether Invio fits your needs or if a custom-built solution makes more sense.