viking

German taxes,
filed from a text file.

viking is a single static binary that submits UStVA, EÜR, ESt and USt returns to your Finanzamt over ELSTER's official ERiC library. Your books stay TSVs, your taxpayer data stays an INI file, and everything lives in git. No accounts, no cloud, no subscription.

linux/amd64 macos/universal windows/amd64 MIT license experimental  0.1.7
steuern-2025  ·  viking session
$ viking init # Created: viking.conf, abzuege.tsv, example.tsv
$ vim viking.conf # you, your spouse, your income sources
$ viking fetch # installs ELSTER's ERiC runtime (~340 MB)
$ viking ustva --test --period q1 --dry-run # validate, print the XML
<?xml version="1.0" encoding="UTF-8"?>
<Elster xmlns="http://www.elster.de/elsterxml/schema/v11"> ...
$ viking ustva --period q1 # the real thing. silent on success, like a Unix tool;
# the server's answer lands in ~/.local/share/viking/viking.<YEAR>.log
ᛝ ᛁ ᚱ ᚢ ᚾ ᛖ

ᚹWhy a CLI for taxes, of all things

vier Anlagen, keine Kompromisse

Anlage AThe portal is a maze

Mein ELSTER means re-typing ninety fields into a browser session every quarter. viking means one INI file and one TSV per project per year, with git diff between filings. Data you entered once stays entered.

Anlage BCommercial tools want a relationship

Subscriptions, accounts, upsells, and your own numbers locked in a database you cannot read. viking is one MIT-licensed binary. The most proprietary thing it touches is the .pfx certificate ELSTER already issued you.

Anlage CValidate like you mean it

Every command takes --dry-run: the real ELSTER plausibility engine runs over your XML, nothing is sent. --test files to the public sandbox with ELSTER's test certificates (PIN 123456) before production ever sees you.

Anlage DNo cloud, no telemetry

The only network traffic goes to elster.de, through the same ERiC library the commercial tools ship. Your data directory is plain files you can back up, grep, and audit: confs, TSVs, logs, PDFs.

ᚠ ᚢ ᚦ ᚨ ᚱ ᚲ

ᚠWhat it files

steuerarten und anlagen

kürzelwasbefehl
UStVAQuarterly VAT advance return. Amounts aggregate from your invoice TSV.viking ustva -s src --period q1
EÜRProfit and loss statement for freelancers and businesses.viking euer -s src
EStIncome tax return, aggregating every source. Anlagen ride along: KAP, S, G, R, Kind, VOR, SA, AgB.viking est
UStAnnual VAT return per source.viking ust -s src
IBANBank account change notification.viking iban
NachrichtFree-text message to your Finanzamt.viking message
PostfachList and download Bescheide and mail from the ELSTER Postfach, confirmations included.viking list, viking download

German words and numerics both work where ELSTER has codes: --period mar or 03, religion = rk or 11, versteuerung = ist or 1.

ᚨ ᚢ ᛊ ᛚ ᚨ ᚾ ᛞ

ᛁInstall

ein binary, drei betriebssysteme

linux · amd64

mkdir -p ~/.local/bin && curl -fsSL -o ~/.local/bin/viking https://github.com/capocasa/viking/releases/latest/download/viking-linux && chmod +x ~/.local/bin/viking

If ~/.local/bin is not on your PATH: bash users add the export to ~/.profile, zsh users to ~/.zshrc. Debian and Ubuntu's stock .profile already adds it once the directory exists.

macos · universal

mkdir -p ~/.local/bin && curl -fsSL -o ~/.local/bin/viking https://github.com/capocasa/viking/releases/latest/download/viking-macos && chmod +x ~/.local/bin/viking

windows · amd64 · PowerShell

md "$env:USERPROFILE\bin" -Force | Out-Null; curl.exe -fsSL -o "$env:USERPROFILE\bin\viking.exe" https://github.com/capocasa/viking/releases/latest/download/viking.exe; $p = [Environment]::GetEnvironmentVariable('Path','User'); if (-not ($p -split ';' -contains "$env:USERPROFILE\bin")) { [Environment]::SetEnvironmentVariable('Path', "$p;$env:USERPROFILE\bin", 'User') }; & "$env:USERPROFILE\bin\viking.exe" --version

Open a new terminal afterwards. ERiC also needs the VC++ Redistributable (winget install Microsoft.VCRedist.2015+.x64), which stock Windows ships without. viking tells you when it is missing.

any os · the ERiC runtime

viking fetch   # downloads and extracts ELSTER's ERiC 43.4.6.0 (~340 MB) into your data dir

Build from source with nimble build if you prefer. Everything else is in the docs.

ᛊ ᛏ ᛖ ᚢ ᛖ ᚱ

ᚲA conf you can actually read

vier sektionen, keine überraschungen

viking.conf
# four section names, no more
[steuerzahler]
name       = Hans Maier
year       = 2025            # copy this dir per year, that's the versioning model
steuernr   = 9198011310010
idnr       = 04452397687
abzuege    = abzuege.tsv

[steuerzahler]               # different name = co-filing spouse
name         = Greta Maier
geburtsdatum = 12.07.1956

[einkommen]                  # typ= dispatches the Anlage
typ          = freiberuflich # S
euer         = freelance.tsv # amount  rate  date  id  description

[einkommen]
typ          = gewerbe       # G, rechtsform inferred from "GmbH" suffix
name         = Musterfirma GmbH
euer         = musterfirma.tsv

[einkommen]
typ          = kapital       # KAP
name         = ibkr

[einkommen]
typ          = rente         # R, rows from rente.tsv
rente        = rente.tsv

[auth]
cert         = viking.pfx    # your ELSTER signing certificate
pin          = viking.pin    # or pincmd = pass show elster/pin

External files are specified explicitly, relative to the conf. A full annotated example ships in the repo's example/ directory.

ᚹ ᛁ ᚲ ᛏ ᛁ ᚷ

ᛊCaution, use --dry-run first

wichtiger hinweis

Wichtiger HinweisSubmissions are irreversible. --dry-run runs the full ERiC validation offline. Verify independently; this is experimental software.