Invoices, clients, expenses and a quarterly tax estimate, without leaving the shell. The same account, the same data and the same rules as the web app: an invoice created here opens in the browser as an ordinary invoice, because it is one.
Install and sign in
$npm install -g nyrut
$nyrut login
Node.js 20 or later. Package: npmjs.com/package/nyrut.
nyrut login opens a loopback server on 127.0.0.1 and sends you to the browser you're already signed into. The web app names the port and asks before handing the session over: a link alone is never enough.
The session is stored at ~/.config/nyrut/session.json with mode 0600. nyrut logout removes it.
Overdue first, then unpaid, then the rest. The footer is the point: what you are owed, and how much of it is late.
nyrut invoice <number>
Draw one invoice.
--plain
no animation
--json
the raw invoice object
$nyrut invoice 2026-014
$nyrut invoice 014
A partial number works if it matches exactly one invoice; if it matches several, you are told which rather than guessed at. This is a preview — the PDF is made in the browser, see nyrut invoice open.
nyrut invoice new [options]
Create an invoice.
--issuer <name>
skip the issuer prompt
--client <name>
skip the client prompt
--date <YYYY-MM-DD>
issue date (default today)
--due <YYYY-MM-DD>
due date (default from the client's terms)
$nyrut invoice new
$nyrut invoice new --client etéreo --issuer nafs
It saves a DRAFT. The number is reserved, nothing is issued, and sending is a separate deliberate step. VAT and withholding come from where your workspace files and where the client is — not from a default.
Shows recipient and total and asks first, because sending cannot be undone. A draft becomes issued the moment it leaves.
nyrut invoice pay <number> [options]
Mark an invoice paid.
--date <YYYY-MM-DD>
when it was actually paid (default today)
--undo
back to unpaid
$nyrut invoice pay 2026-014
$nyrut invoice pay 2026-014 --date 2026-08-01
nyrut invoice link <number>
Public link to share the invoice.
$nyrut invoice link 2026-014
$nyrut invoice link 2026-014 | pbcopy
Creates the link the first time and reuses it after. Anyone holding it can see the invoice — the URL is the credential. The warning goes to stderr so piping copies only the link.
nyrut invoice open <number>
Open the invoice in the browser.
$nyrut invoice open 2026-014
Where the PDF lives, and where you can edit it.
nyrut clients
Your clients and what each still owes.
--json
raw client objects
nyrut issuers
Your issuing entities.
--json
raw issuer objects
The type column decides which tax forms apply: an individual files modelo 130, a company does not.
nyrut expenses [options]
Expenses you have recorded.
--year <YYYY>
only this year
--limit <n>
how many (default 20)
--all
no limit
--json
raw expense objects
nyrut summary [options]
VAT by quarter, for one issuer.
--year <YYYY>
which year (default this one)
--issuer <name>
which issuer (default the first)
--json
the quarters as data
$nyrut summary
$nyrut summary --year 2025 --issuer nafs
One issuer at a time, always: VAT is filed per tax ID, so adding two together produces a number matching no return anyone will ever file. Invoices in another currency are excluded and counted — converting them needs the ECB rate per date, which the app fetches. An estimate to check against, not a filing.
nyrut login
Sign in through your browser.
Opens a loopback server on 127.0.0.1 and sends you to the browser you are already signed into. The web app names the port and asks before handing anything over. The token is stored at ~/.config/nyrut/session.json with mode 0600.
nyrut logout
Forget the session on this machine.
nyrut whoami
Who you are signed in as.
Scripting
--json works on every listing, and it's a separate code path: no colour, no padding, no headers.
Colour never carries meaning: every line reads correctly through | cat, on a dumb terminal and under NO_COLOR.
Animation stops when nobody is watching: not a TTY, piped, CI, NO_COLOR or --plain.
Spinners go to stderr, so nyrut invoice link 2026-014 | pbcopy copies the URL and nothing else.
Unknown options are an error: --stauts=paid won't silently list every invoice.
Taxes
nyrut summary runs the app's own 303 and 130 calculations, one issuer at a time (VAT is filed per tax ID). Invoices in another currency are excluded and counted, because converting them needs the ECB rate of each invoice's date. It's an estimate to check against, not a filing.