I'm Finance Ops, not a developer. I built a KoSIT-valid XRechnung generator in the browser anyway
Source: Dev.to
Background
My day job is Finance Ops and accounting, not software engineering. In the DACH region the gap between what accountants need and what developers build is real—and expensive—so I decided to close it myself.
The Regulatory Context
Germany’s E‑Rechnungspflicht is no longer theoretical.
- B2G (Business‑to‑Government) invoicing has required a valid XRechnung for years.
- B2B rollout is phased: reception from 2025, issuance for > €800 k revenue from 2027, and broad adoption from 2028.
A PDF— even a perfect one— is not enough.
Existing Solutions
Every tool I found fell into one of three categories:
| Category | Example | Drawbacks |
|---|---|---|
| Enterprise ERP | SAP, DATEV | Full XRechnung support, but costs hundreds of euros/month; built for teams, not freelancers |
| SaaS invoicing | Lexoffice, sevDesk | Subscription‑based; invoice data lives on their servers; lock‑in by design |
| CLI tools | Open‑source Java/Python libraries | Assume you know how to run java -jar or similar command‑line tools |
The Missing Middle
Freelancers, one‑person consultancies, and Kleinunternehmer who need to invoice public authorities (e.g., the municipality of Hamburg) once a quarter lack a suitable, low‑cost solution. That’s who I built this for—also for myself.
Solution: Browser‑Native XRechnung Generator
- Zero‑server, zero‑account: All processing happens locally in the browser; no data leaves your machine.
- Live demo: (local‑first, zero tracking)
- Validation: KoSIT Validator v1.6.2 (Config v3.0.2) + EN 16931. Supports both UBL 2.1 and UN/CEFACT CII syntax.
- Source code: (MIT license)
Key Characteristics
- Invoice data (client names, project descriptions, amounts, IBANs) is high‑signal.
- XML generation, PDF rendering, and pre‑validation run entirely in the browser.
- Network traffic: Zero outbound requests (verified via DevTools Network tab).
Development Approach
My role is more architect/orchestrator than “code‑all‑day” developer. The workflow:
- Read the EN 16931 spec and map the domain model into TypeScript types.
- Define validation rules based on the spec.
- Implement the generator, keeping the domain model syntax‑agnostic (produces both UBL 2.1 and CII from the same Invoice object).
AI Assistance
Parts of the implementation were AI‑assisted (Claude Code / Codex) under my architecture, with manual review and validation loops. This forced a deep understanding of the standard because you cannot “prompt your way past” a KoSIT schema validation error you don’t understand.
Hardest Challenge
Building a typed domain model that outputs both UBL 2.1 and CII without branching logic everywhere. The same invoice object yields two syntax outputs, keeping the core model clean.
Deployment
- Every push to
mastertriggers a GitHub Actions workflow that builds and deploys to Cloudflare Pages. - No servers, containers, or databases are involved.
- Static assets are cached at Cloudflare’s edge, resulting in near‑zero latency (“the file is already there”).
Lessons Learned
- Read the full EN 16931 + CIUS context before touching any code.
- XRechnung is not “just XML with German quirks.” It layers EN 16931 Core, CIUS, and KoSIT profile requirements.
- URN identifiers alone took two days to get right and are a common cause of validation failures even when invoice data is correct.
- Typed constants (
constvalues in TypeScript) eliminated an entire class of errors—worth knowing upfront.
Call for Feedback
If you’ve worked with XRechnung, EN 16931, or Peppol:
- What validation errors do you see most often in production?
- Do your clients’ ERPs consume UBL or CII?
- What is the one missing feature that would make this generator useful for you?
Technical Breakdown
A full architectural and code walkthrough is available at: