Modern Invoice Template for Typst
A professional, compliant, and automated invoice template for Typst. This package follows the German DIN 5008 standard (Form A & B) and automates calculations, VAT handling, and payment details.
![]()
Features
- DIN 5008 Compliant: Supports both Form A and Form B layouts.
- Automatic Calculations: Handles line items, sub-totals, and VAT (MwSt) automatically.
- EPC QR-Code (GiroCode): Generates a scannable banking QR code for easy payment apps using
rustycure. - Flexible Tax Settings: Supports standard VAT (Brutto/Netto modes).
- Kleinunternehmerregelung: Built-in support for small business exemption (§ 19 UStG).
- Customizable: Easy configuration of sender, recipient, payment goals, and bank details.
Getting Started
Installation
Import the package at the top of your Typst file:
#import "@preview/invoice-pro:0.1.1": *
Basic Usage
Here is a minimal example of how to create an invoice:
#import "@preview/invoice-pro:0.1.1": *
// Set language to German for correct date/number formatting
#set text(lang: "de")
#show: invoice.with(
format: "DIN-5008-A", // or "DIN-5008-B"
sender: (
name: "Deine Firma / Name",
address: "Musterstraße 1",
city: "12345 Musterstadt",
extra: (
"Tel": [+49 123 4567890],
"Web": [#link("https://www.example.com")[www.example.com]],
)
),
recipient: (
name: "Kunden Name",
address: "Kundenstraße 5",
city: "98765 Kundenstadt"
),
invoice-nr: "2024-001",
date: datetime.today(),
tax-nr: "123/456/789",
)
// Add Invoice Items
#invoice-line-items(
item([Consulting Service], quantity: 4, unit: [hrs], price: 80),
item([Software License], price: 150),
)
// Payment Terms
#payment-goal(days: 14)
// Bank Details with QR Code
#bank-details(
bank: "Musterbank",
iban: "DE07100202005821158847",
bic: "MUSTERBIC",
)
#signature(signature: block[Your Signature])
Configuration
invoice arguments
| Argument | Type | Description |
|---|---|---|
format |
string | “DIN-5008-A” or “DIN-5008-B” (Default: B). |
sender |
dict | Sender details (name, address, city, extra). |
recipient |
dict | Recipient details. |
vat |
float | Default VAT rate (e.g., 0.19 for 19%). |
vat-exempt-small-biz |
bool | If true, enables “Kleinunternehmer” mode (no VAT). |
show-gross-prices |
bool | If true, calculates B2C gross prices. Default is false (B2B/Net). |
invoice-line-items function
| Argument | Type | Description |
|---|---|---|
vat-exemption |
bool | auto |
Overrides the global setting. auto inherits from invoice. |
show-quantity |
bool | auto |
Controls the quantity column. auto hides it if all quantities are 1. |
show-vat-per-item |
bool | auto |
Controls the VAT column. auto shows it only if VAT rates differ between items. |
currency |
content |
The currency symbol to display (Default: [€]). |
show-gross-prices |
bool |
Calculation mode: false (Default/B2B) for net prices, true (B2C) for gross prices (prevents rounding errors). |
..items |
arguments |
A list of item() calls. |
item function
| Argument | Type | Description |
|---|---|---|
description |
content | Description of the service/product. |
price |
float | Price per unit. |
quantity |
float | Amount (Default: 1). |
vat |
float | Specific VAT rate for this item (overrides default). |
Line items with VAT exemption
#invoice-line-items(
vat-exemption: true,
item([Consulting Service], quantity: 4, unit: [hrs], price: 80),
item([Software License], price: 150),
)

Line items B2C relation
#invoice-line-items(
show-gross-prices: true,
item([Fresh Mango], quantity: 4, unit: [pc.], vat: 0.07, price: 3.50),
item([Döner Kebap to Go], unit: [pc.], price: 8),
)

Line items B2B relation
#invoice-line-items(
item([Ergonomic Office Chair "Modell Air"], quantity: 10, price: 250.00, gross-price: false, unit: [pc.]),
item([Monitor Mount VESA 100], quantity: 20, unit: [pc.], gross-price: false, price: 45.50),
item([Shipment], quantity: 1, gross-price: false, price: 89.90),
)

payment-goal function
| Argument | Type | Description |
|---|---|---|
days |
int | none | The number of days until payment is due. |
date |
datetime | content | none | A date until payment is due. |
currency |
content |
The currency symbol to display (Default: [€]). |
#payment-goal()
Bitte überweisen Sie den Gesamtbetrag von 123,45€ zeitnah ohne Abzug auf das unten genannte Konto.
#payment-goal(days: 14)
Bitte überweisen Sie den Gesamtbetrag von 123,45€ innerhalb von 14 Tagen ohne Abzug auf das unten genannte Konto.
#payment-goal(date: datetime(day: 1, month: 1, year: 2026))
Bitte überweisen Sie den Gesamtbetrag von 123,45€ bis spätestens 01.01.2026 ohne Abzug auf das unten genannte Konto.
bank-details function
Renders a block containing the bank details and an optional EPC-QR-Code (GiroCode) for easy mobile payment.
| Argument | Type | Description |
|---|---|---|
bank |
str |
content |
iban |
str |
Required. The IBAN (formatting is handled automatically). |
bic |
str |
Required. The BIC (Bank Identifier Code). |
name |
auto |
str |
reference |
str |
none |
show-refernce |
bool |
Toggles visibility of the reference line. (Note: Parameter is currently spelled show-refernce) . |
payment-amount |
float |
auto |
account-holder-text |
str |
content |
qr-code |
dictionary |
Configuration for the QR code (display: bool, size: length). Default size is 4em. |
// Standard usage with automatic total and reference
#bank-details(
bank: "Sparkasse Musterstadt",
iban: "DE00 1234 5678 9012 3456 78",
bic: "SPKDE...",
)
// Customizing the QR code size and reference text
#bank-details(
bank: "Neo Bank",
iban: "DE99...",
bic: "NEO...",
reference: "Rechnungs-Nr. 2024-001 / Kundennummer 55",
qr-code: (size: 3cm)
)
// Hiding the QR Code
#bank-details(
bank: "Oldschool Bank",
iban: "DE11...",
bic: "OLD...",
qr-code: (display: false)
)
Dependencies
This template relies on these amazing packages:
letter-profor the DIN layout.rustycurefor QR-Code generation.ibanatorfor IBAN formatting.
Acknowledgements:
- Special thanks to classy-german-invoice by Kerstin Humm, which served as inspiration and provided the logic for the EPC-QR-Code implementation.
License
MIT