← Back to Portfolio
Case Study6 min read

How I built a SaaS for
EU invoicing.

A production invoice generator serving freelancers across 7 EU countries. Three invoice types, seven languages, client-side PDF generation, and a Stripe-powered freemium model. Built and shipped solo.

Visit Site
7
Countries
3
Invoice Types
379
Tests
€12
/month
€0
Server PDF Cost
Scroll to explore
00The Problem

EU invoicing is broken.

Freelancers across Europe deal with the same frustration. Every country has different VAT rates, different tax ID formats, different legal requirements. A Slovak invoice needs IČO, DIČ, and IČ DPH fields. A German one needs Steuernummer and USt-IdNr. A French one needs SIRET and RCS. Miss one field and the invoice isn’t legally valid.

Existing tools are either US-focused, expensive, or try to do everything. Most freelancers end up with Word templates and manual calculations. I built euinvoice to solve this for real. A free tool that handles the complexity so the user doesn’t have to.

01Core Logic · VAT Engine

Seven countries. Three invoice types.

The heart of euinvoice is its VAT engine. Each of the seven supported countries (Slovakia, Germany, Austria, Netherlands, Poland, Czech Republic, and France) has its own VAT rate, small business threshold, legal text, tax ID fields, and date format. A single configuration object drives the entire app: forms, PDF output, validation, and SEO pages all read from one source of truth.

The engine handles three invoice types automatically. Standard VAT invoices apply the correct country rate. Reverse charge invoices are auto-detected when the supplier and client are in different EU countries and the client has a valid VAT ID. The tax liability shifts to the buyer under Article 196. VAT-exempt invoices apply when the supplier is below their country’s small business threshold. All calculations use floating-point-safe arithmetic to prevent rounding errors on financial amounts.

Tech Stack
TypeScriptNext.js7 EU CountriesArticle 196
Countries
SK, DE, AT, NL, PL, CZ, FR
Types
Standard VAT, reverse charge, VAT exempt
Precision
IEEE 754-safe rounding for financial math
7 EU countries supported
🇸🇰SK23%
🇩🇪DE19%
🇦🇹AT20%
🇳🇱NL21%
🇵🇱PL23%
🇨🇿CZ21%
🇫🇷FR20%
02Output · Client-Side PDF

PDFs generated in the browser.

Every invoice PDF is generated entirely in the browser using @react-pdf/renderer. No server call, no queue, no infrastructure cost. The user fills in the form, clicks download, and the PDF renders client-side in milliseconds. Data never leaves the browser.

The PDF adapts to context. Domestic invoices use the local language for labels: FAKTÚRA for Slovakia, RECHNUNG for Germany, FACTURE for France. Cross-border invoices switch to English automatically. Legal notices are country-specific: Slovakia cites § 69 ods. 12, Germany references § 13b UStG. Tax ID fields shown on the PDF match the supplier’s country requirements. The result is a legally compliant document that looks correct regardless of which two EU countries are involved.

Tech Stack
@react-pdf/rendererReact 18Intl.NumberFormat
Rendering
Client-side with @react-pdf/renderer
Languages
Domestic = local language, cross-border = English
Cost
Zero server infrastructure for PDF generation
Client-side PDF generation
INVOICE
DescriptionVATAmount
20%€2,400.00
20%€800.00
10%€150.00
Subtotal€3,350.00
VAT 20%€640.00
VAT 10%€15.00
Total€4,005.00
Auto-detected language
Multi-rate VAT breakdown
Country-specific legal text
03Localization · 7 Languages

Not just translated. Fundamentally different.

Internationalization in euinvoice goes far beyond translating strings. The UI runs in seven languages: English, German, Slovak, Polish, Czech, French, and Dutch. But each language also means different form fields, different validation rules, and different business logic.

A Polish invoice shows NIP as the tax identifier. A Dutch one shows KVK-nummer. A German invoice under the small business exemption gets Kleinunternehmerregelung legal text, while a Czech one gets Osvobození od DPH. Dates format differently: dd.MM.yyyy in Germany, dd/MM/yyyy in France, dd-MM-yyyy in the Netherlands. Currency switches automatically. EUR for most countries, CZK for Czech Republic, PLN for Poland. Every combination of language, country, and invoice type produces a different but legally correct result.

Tech Stack
7 Languages7 CurrencieshreflangJSON-LD
UI Languages
EN, DE, SK, PL, CS, FR, NL
PDF Languages
7 PDF output languages with auto-switching
Fields
Country-specific tax IDs, date formats, currencies
7 languages, 7 sets of business rules
ENVAT Number
DEUSt-IdNr.
SKIČ DPH
PLNIP
CSDIČ
FRN° TVA
NLBTW-nr.
04Data · Supabase + RLS

Row-level security. By default.

The database runs on Supabase PostgreSQL with Row-Level Security enforced on every table. Users can only access their own profiles, invoices, and clients. Not through application logic, but through database policies. Even if the API is misused, the data stays isolated.

Invoices store supplier and client details as JSONB snapshots, decoupling history from the current profile. If a user updates their address, existing invoices remain unchanged. An atomic counter tracks global invoice generation for social proof on the landing page. Account deletion cascades through all related data. Data export generates a full JSON dump for GDPR portability. Magic link authentication via Resend means no passwords to store or breach.

Tech Stack
SupabasePostgreSQLRLSResend
Auth
Magic link authentication via Resend
Security
RLS on every table, GDPR-compliant deletion and export
Features
JSONB invoice snapshots, atomic counters
Row-Level Security on every table
users
email
company
tier
documents
type
snapshot
totals
line_items
desc
rate
amount
contacts
name
tax_id
country
counters
key
value
05Revenue · Stripe

Freemium that actually works.

euinvoice uses a three-tier freemium model. The free tier lets anyone generate unlimited invoices without an account. Data stays in the browser. Creating a free account adds invoice history, supplier auto-fill, and saved invoices. The Pro tier at €12/month unlocks a client directory, custom invoice numbering, and priority support.

Stripe handles the payment infrastructure. Checkout sessions create subscriptions, webhooks manage the lifecycle: upgrading the user’s tier on successful payment, downgrading on cancellation. The customer portal lets users manage their subscription without touching the app. Webhook signature verification ensures every event is genuine. The free tier is generous enough to drive adoption, and the Pro features solve real workflow pain points that grow with the user’s business.

Tech Stack
StripeWebhooksCustomer PortalFreemium
Tiers
Free forever, free account, Pro at €12/month
Billing
Stripe Checkout, webhooks, customer portal
Pro Features
Client directory, custom numbering, priority support
Free → Account → Pro
Free
€0forever
Unlimited invoices
7 countries
Client-side PDF
Account
€0forever
Invoice history
Supplier auto-fill
Data export
Pro
€12/month
Client directory
Custom numbering
Priority support
06Quality · 379 Tests

Every edge case. Covered.

Financial software has no room for bugs. A rounding error on a VAT calculation means an incorrect invoice. A missed reverse charge detection means tax liability in the wrong country. So every critical path is tested.

379 Vitest tests cover VAT calculations with floating-point edge cases, reverse charge auto-detection across all country pairs, PDF output validation for all three invoice types, country-specific legal text and tax ID visibility, Pro tier feature gating, and client directory pre-fill behavior. The test suite runs in under 200 milliseconds. Sentry tracks errors in production across client, server, and edge runtimes. Umami provides privacy-first analytics without cookies.

Tech Stack
VitestSentryUmamiTypeScript
Framework
Vitest, 379 tests in under 200ms
Coverage
VAT math, reverse charge, PDF output, Pro gating
Monitoring
Sentry error tracking, Umami analytics
379 tests passing
VAT Math
Floating Point
Reverse Charge
PDF Output
Pro Gating
Integration
0 / 379 passing
The Takeaway

One developer.
Production SaaS.

euinvoice.app is proof that one person can build, monetize, and maintain a compliant multi-country SaaS product. Every VAT rule, every PDF, every test. Built and shipped solo.