My ecosystem of personal apps: a single app, in the browser and on Windows and Android, where each app is a section, today Spese (expenses) and Inventario (inventory). The data lives on the device and works offline; my server syncs it, also in areas shared with other people and with end-to-end encryption. Try it without an account, with sample data.
Oriel is my ecosystem of personal apps: a single app, in the browser and as an app for Windows and Android, where each app is a section with its own data, on top of a shared database, sync engine and component library. The first section is **Spese** (Italian for "expenses"), the successor of Spiccio, rewritten here one piece at a time; the second, **Inventario** ("inventory"), keeps track of household items with their warranties and receipts. From the link you can try it without an account: «Prova con dati d'esempio» (try with sample data) opens Spese with made-up accounts and transactions that stay in that browser.
**What it does**
- **Works offline**: the data lives on the device, in SQLite (in the browser through WebAssembly, with OPFS), and the server carries it to the other devices; an update sends only the fields that changed. - **Spese**: accounts, transactions, refunds, subscriptions with cancellation and notice period, monthly budgets, balance forecast, CSV import and a Review that finds duplicates and conflicts. - **Inventario**: an item is created from an expense, with the receipt attached and the warranty that runs out. - **Shared areas**: data in common with other people, invited with a link, with who is there right now, a transaction locked while someone else edits it and changes in real time. - **End-to-end encryption**, optional: the server only holds encrypted data, and removing someone from an area changes its key. - **Sign-in** with password, passkey and one-time code; a save can be undone.
**The hard part**
Two devices changing the same transaction while offline: the server never overwrites, it keeps both versions and the conflict card shows what changed, where and who did it, until someone chooses. Rules that tie several records together, such as refunds that cannot exceed the expense, are checked by the server too, and the conflict says which rule stopped it.
Vue 3 and TypeScript, Fastify and PostgreSQL on my own server in Docker, Tauri 2 for the native apps: 22 packages in a monorepo, every module documented in a catalogue, more than 5,000 automated tests and about a hundred end-to-end tests in a real browser.
Design, full-stack development and deployment · 2026
Vue.js, Fastify, PostgreSQL, SQLite, Tauri