Tally — simple quotes and invoices
Quotes and invoices without accounting software: lines that do the math by themselves, total and VAT automatic, print or PDF in one click.
data space «studio-en» — the suite’s glue: on your device, multi-user with one invite (link or QR), end-to-end encrypted.
▶ Open the suite (2 micro apps)
Integrates with: Compass — same data space.
What it records
- Document number (e.g. 2026-042)
- Description
- Quantity
- Unit price (€)
- Company name
- VAT number / tax ID
- Address
Composed of 2 micro apps
One job each, over the same data: every micro app reads and writes the shared data space “studio-en” (with your consent, asked on first open). Everything stays on your device — and with a single invite the whole suite goes multi-user, end-to-end encrypted.
Shared micro apps are the bridge between solutions: the same data also powers Compass.
How it works
This is a Reactive app: a plain text document that your browser turns into a working app — forms, live data, tables, statistics and even charts, with nothing to install or configure.
- Use it right away. Hit “Use this app”: it opens right in your browser, ready to go, with data saved only on your device.
- Your data stays yours. Everything is stored locally on your device, kept separate for each app: no account, no server, nothing to set up.
- Make it your own. The text below is the entire app: copy it, tweak fields, views and words, and your changes become interactive instantly.
- Share it as a file. An app is a simple file: save it, export it or share it with a link; and with encrypted collaboration several people edit the same data in real time.
The app’s source
# 🧾 Tally
Quotes and invoices without accounting software: lines that do the math by themselves, total and VAT automatic, print or PDF in one click.
:::::page{title="Document" icon="🧾"}
## Header
::input[docnum]{placeholder="Document number (e.g. 2026-042)" legend="Number"}
::select-from[billto]{from="clients" label="name" value="name" legend="Billed to"}
::input[docdate]{type="date" legend="Date"}
## Lines
::::form{path="lines" id="frg"}
::input{form="frg" field="item" placeholder="Description" required="true"}
::input{form="frg" field="qty" type="number" placeholder="Quantity" required="true"}
::input{form="frg" field="price" type="number" placeholder="Unit price (€)" required="true"}
::add-form{form="frg" path="lines" label="Add line"}
::::
::::card{id="documento" title="Document"}
**No.** :value[vnum]{ref="#docnum"} — **to:** :value[vint]{ref="#billto"} — **dated** :value[vdata]{ref="#docdate"}
:::table{path="lines" headers="Item,Qty,Price,Subtotal" deletable="true" editform="frg" search="false" pagesize="0"}
{item} | {qty} | € {price} | € {qty*price}
:::
**Net amount: € :sum[imp]{path="lines" field="qty*price"}** ·
VAT 22%: € :sum[ivaval]{path="lines" field="qty*price*0.22"} ·
**Total: € :sum[tot]{path="lines" field="qty*price*1.22"}**
::::
::print{target="documento" label="Print / PDF"}
> Finished a document? Print it or save it as PDF, then clear the lines with
> the trash bins to start the next one. Each app version keeps its own data.
:::::
:::::page{title="Clients" icon="👥"}
## Directory
::::form{path="clients" id="fcl"}
::input{form="fcl" field="name" placeholder="Company name" required="true"}
::input{form="fcl" field="vatid" placeholder="VAT number / tax ID"}
::input{form="fcl" field="address" placeholder="Address"}
::input{form="fcl" field="email" type="email" placeholder="Email"}
::add-form{form="fcl" path="clients" label="Add client"}
::::
:::table{path="clients" headers="Client,VAT no.,Address,Email" deletable="true" editform="fcl"}
**{name}** | {vatid} | {address} | {email}
:::
:::::