Offline-first Rechnungen für deutsche Freelancer und Kleinunternehmer. ZUGFeRD- / Factur-X-konforme PDF/A-3 mit eingebettetem EN-16931-XML — lokal, ohne Cloud, ohne Abo.
Ich bin Solo-Selbstständig und hatte keine Lust auf weitere 20–30 € pro Monat für SaaS-Buchhaltung, nur um ein paar Rechnungen pro Quartal zu schreiben. Erst recht nicht, wenn meine Buchhaltungs-Daten dann irgendwo in einem AWS-Bucket eines deutschen GmbH-mit-niederländischer-Holding-Konstrukts liegen.
Zettel ist das, was dabei rausgekommen ist: ein kleines Desktop-Tool, das lokal läuft, die deutsche E-Rechnungs-Norm EN 16931 korrekt umsetzt, den Kleinunternehmer-Modus (§ 19 UStG) als First-Class-Feature behandelt — und keine Telemetrie sendet, weil es keinen Server gibt, an den es senden könnte.
| SaaS-Tools | Zettel | |
|---|---|---|
| Hosting | Cloud (DSGVO-AVV nötig) | Dein Rechner |
| Kosten | 15–40 €/Monat | Einmalig 0 € |
| Daten-Eigentum | Vendor-Lockin | SQLite-File auf deiner Disk |
| ZUGFeRD-XML | Häufig nur ab Premium | Standard, alle Profile |
| Funktioniert offline | Selten | Immer |
| Internet weg → kein Backup? | Problem | Egal |
- PDF/A-3 mit eingebettetem Factur-X-XML in den Profilen BASIC, EN 16931 und EXTENDED
- Kleinunternehmer-Modus mit korrektem
CategoryCode Eund BR-CO-26-konformemBT-29-Fallback ohne USt-IdNr. - Reverse-Charge intra-EU (CategoryCode K) und Drittland (CategoryCode G) inkl. Pflicht-Hinweistexte
- Stornorechnungen als first-class Credit-Notes mit korrektem CII-Schema
- Mehrere USt-Sätze pro Rechnung (0 %, 7 %, 19 %), Multi-Currency mit eingefrorenem EUR-Wert
- Drei PDF-Themes (classic / modern / minimal) per CSS-Variablen
- Leistungszeiträume (BG-14 / BG-26) auf Header- und Positions-Ebene, lange Positions-Beschreibungen (BT-154)
- Eingangsrechnungen mit Drop-Zone für ZUGFeRD-PDFs (automatisches Parsing) und OCR-Light-Fallback (Text-Layer-Extraktion, kein Tesseract)
- Lieferanten-Verwaltung mit USt-IdNr.-Matching beim Drop
- DATEV-Export (Format 700, SKR03/SKR04) — Erlöse, Aufwände und Stornos in einem Buchungsstapel
- UStVA-Vorbereitung (Kennzahlen 81/86/41/21/66 pro Quartal, zum Abtippen)
- Mahnungen als eigene Dokumentenklasse mit Nummernkreis
MA-…
- § 32a EStG-Tarif für VZ 2024, 2025 und 2026 hartcodiert aus amtlicher BMF-Bekanntmachung, 38 Testfälle
- Splittingtarif für Verheiratete, Soli mit Milderungszone, KiSt 8/9 %, GewSt mit § 35-Anrechnung
- Pauschal-Modus (% × Umsatz) als zusätzliche Sanity-Check-Anzeige
- YTD-Modus vs. Hochrechnung; Quartals-Vorauszahlungen werden gegengerechnet
- Nebenberuf: marginale ESt-Berechnung wenn
other_income_annual_centgesetzt ist
- Zeitraum-Switcher (Jahr / Quartal / Monat / Custom) mit YoY-Kontext
- Globale Suche (
Cmd/Ctrl+K) über alle Entities inkl. Item-Beschreibungen - Wiedervorlage-Liste pro Kunde/Rechnung mit
follow_up_date - Interne Notizen (nicht auf der PDF)
- Wiederkehrende Rechnungen (monatlich / quartalsweise / jährlich) — explizit per Klick erzeugen, kein stilles Background-Cron
- Backup als verschlüsseltes ZIP (AES-256-GCM + Argon2id) oder unverschlüsselt
- Granularer Restore (Kunden / Rechnungen+PDFs / Settings unabhängig)
- Sandbox-Modus mit separater DB zum Ausprobieren
- Auto-Update Ed25519-signiert via GitHub Releases
- Danger Zone mit Auto-Backup vor jeder destruktiven Aktion
Vorgebaute Installer für Windows, macOS und Linux: latest release.
| Plattform | Format | Hinweis |
|---|---|---|
| Windows 10/11 | .msi, .exe (NSIS) |
Beim ersten Start: SmartScreen → Weitere Informationen → Trotzdem ausführen |
| macOS 14+ (Apple Silicon) | .dmg |
Nicht notarisiert — Rechtsklick → Öffnen. Intel-Build pausiert (CI-Capacity) |
| Linux (Ubuntu 22.04+) | .deb |
System-Pango/Cairo nötig (siehe unten) |
Linux / macOS Systempakete (WeasyPrint lädt Pango und Cairo dynamisch):
# Ubuntu / Debian
sudo apt install libpango1.0-0 libcairo2 libgdk-pixbuf2.0-0
# macOS
brew install pango cairo gdk-pixbufAuto-Update ist ab v0.4.3 aktiv. Ältere Installationen einmal manuell auf die aktuelle Version ziehen.
- Einstellungen → Unternehmen öffnen, Firmendaten + Steuernummer (bzw. USt-IdNr.) eintragen
- Einstellungen → Steuerprofil ausfüllen, damit das Dashboard die Steuer-Rücklage berechnen kann
- Kunde anlegen (
/customers/new) - Neue Rechnung → Kunde wählen → Positionen → speichern
- PDF erzeugen →
~/Documents/Zettel/Rechnungen/RE-2026-0001.pdf
Für eingehende Rechnungen: /expenses öffnen, PDF in die Drop-Zone ziehen — ZUGFeRD-XML wird automatisch geparsed, Vendor via USt-IdNr. gematcht.
Bewusst ausgeschlossen — diese Dinge sind im Scope anderer Tools besser aufgehoben:
- Keine vollständige Buchhaltung (kein doppelter Eintrag, kein Konten-Plan, kein Jahresabschluss)
- Kein Banking / Kontoabgleich — Zahlungen werden manuell gemarkt
- Kein ELSTER-Upload und kein UStVA-Versand — Zettel bereitet vor, du tippst ab oder gibst es dem Steuerberater
- Keine Cloud, kein Sync, keine Mobile-App — bewusst nicht in Scope
- Kein SMTP-Versand — Rechnungen landen als PDF, du schickst sie wie du willst
- Kein Tesseract-OCR — gescannte Belege funktionieren nicht und sollen es auch nicht
- Keine Telemetrie — es gibt buchstäblich keinen Server, der was empfangen könnte
┌─────────────────────────────────────────────────────────┐
│ Frontend Svelte 5 (runes) · Tailwind v4 · Bits UI │
│ svelte-spa-router (hash) │
└────────────────────────┬────────────────────────────────┘
│ Tauri Commands
┌────────────────────────┴────────────────────────────────┐
│ Rust Tauri 2 · plugin-sql · Updater · ureq │
│ AES-256-GCM Backup · Sandbox · ECB-Kurs │
└──────────┬──────────────────────────┬───────────────────┘
│ spawn(stdio JSON) │ SQLite
▼ ▼
┌───────────────────┐ ┌──────────────┐
│ Python Sidecar │ │ zettel.db │
│ WeasyPrint │ │ (SQLite) │
│ factur-x · lxml │ └──────────────┘
│ pypdf │
└───────────────────┘
- Frontend (
src/) — Svelte 5 mit Runes, hash-Routing viasvelte-spa-router, UI als shadcn-Style-Wrapper über Bits UI insrc/lib/ui/ - Persistenz (
src/lib/db/) — SQLite direkt via@tauri-apps/plugin-sql. Schema-Typen aus Drizzle (nur compile-time), Queries als raw parameterized SQL. Migrations werden compile-time viainclude_str!in den Rust-Layer eingebettet - Rust (
src-tauri/src/) — Tauri-Commands, Backup, Crypto, Sandbox, ECB-Wechselkurs, Sidecar-Bridge - Python-Sidecar (
sidecar/) — JSON-RPC über stdin/stdout. PDF-Rendering via WeasyPrint + Jinja2, ZUGFeRD-XML viafactur-x, eingehende PDFs viafactur-x.extractoderpypdf-Heuristik. PyInstaller-gebundelt im Release-Build
Implementierungs-Details und Konventionen: CLAUDE.md. DATEV-Mapping: docs/datev-export.md.
git clone https://github.com/jonax1337/zettel
cd zettel
pnpm install
# Sidecar-Venv für dev
cd sidecar
python -m venv .venv
# Windows:
.\.venv\Scripts\Activate.ps1
# macOS / Linux:
source .venv/bin/activate
pip install -r requirements.txt
cd ..
pnpm tauri:devRelease-Build (mit gebundeltem Sidecar):
cd sidecar && python build.py && cd ..
pnpm tauri:buildVollständige Plattform-Voraussetzungen (GTK3-Runtime auf Windows, Tauri-System-Deps, Python 3.12) und Konventionen: CONTRIBUTING.md.
Geplant — siehe Issues und Discussions. Größere Themen, die in Diskussion sind:
- I18n (englische UI als zweite Sprache)
- AfA / Anlageverzeichnis
- EÜR-Export
- Mandanten-Profile (mehrere Firmen in einer Installation)
Was bereits drin ist: CHANGELOG.md.
Issues, Patches und Vorschläge sind willkommen. Setup, Konventionen und PR-Workflow in CONTRIBUTING.md. Code of Conduct in CODE_OF_CONDUCT.md.
Gute Einstiegspunkte: Issues mit Label good first issue und help wanted.
Zettel ist keine Rechts- oder Steuerberatung. Die erzeugten Rechnungen sind nach bestem Wissen EN-16931-konform, aber ohne Garantie. Die ersten Rechnungen vor dem Versand vom Steuerberater prüfen lassen. Die Steuer-Rücklage-Berechnung ist eine Vorhersage, kein Steuerbescheid — Quartals-Vorauszahlungen, individuelle Sonderausgaben und außergewöhnliche Belastungen werden nicht berücksichtigt.
MIT — © Jonas Laux & Contributors · laux.digital
Dieses Projekt würde ohne diese tollen Open-Source-Tools nicht existieren: Tauri, Svelte, WeasyPrint, factur-x, Bits UI, Lucide. Validierung über erechnungs-validator.de und den KoSIT-Validator.