One submit, and the numbers move together.
Tabula is an ERP for small and medium businesses. Submitting a sales invoice allocates its number, locks its lines, and posts every stock movement it causes — in a single database transaction, or none of it at all.
No credit card. Self-hosted or hosted.
The stock moved the moment the invoice did.
No overnight sync, no “post to inventory” step someone forgets on a Friday. Submitting INV-2026-00042 wrote these ledger entries inside the same transaction that created it.
If any part of it failed — a number collision, a short stock check — the whole thing rolls back. You never end up with an invoice whose goods never left the warehouse.
| Item | Out | Balance | Value (FIFO) |
|---|---|---|---|
| Steel bracket, 12 mmITEM-0007 | −120 | 380 | ₱29,640.00 |
| Hex bolt M8 — box of 50ITEM-0012 | −24 | 36 | ₱7,560.00 |
Posted by INV-2026-00042 · same transaction · reversed automatically if the invoice is cancelled
Every document walks the same four states.
Invoices, purchase orders, stock entries — one lifecycle, learned once, enforced by the database rather than by habit.
- 01Draft
The only state you can freely edit. Nothing has been numbered or posted yet.
- 02Submitted
Number allocated, lines locked, stock posted — one transaction, or none of it.
- 03Paid
Payments applied against the document; outstanding recalculated as they land.
- 04Cancelled
Reversed with a matching entry and an audit row. The original never disappears.
Eight modules. Two of them are done.
Tabula is built in phases, in public. Here is exactly where it stands today.
- SalesCustomers, items, invoices, payments, receivablesShipped
- InventoryMulti-warehouse, batches, stock ledger, FIFO valuationShipped
- PurchaseSuppliers, purchase orders, receipts, billsIn progress
- AccountingDouble-entry ledger, statements, fiscal periodsPlanned
- CRMLeads, opportunities, quotationsPlanned
- HR & PayrollEmployees, attendance, payroll runsPlanned
- ManufacturingBOMs, work orders, production planningPlanned
- ProjectsTasks, timesheets, project costingPlanned
Each organization gets its own Postgres schema — t_acme, t_northwind — so one tenant's data cannot be queried from another's session, by construction rather than by a WHERE tenant_id everyone has to remember.
Boring where boring is correct.
Money is a decimal, never a float. Documents are immutable once submitted. The unglamorous parts are the product.
- Next.js 16
- TypeScript
- Prisma + Postgres (Neon)
- shadcn/ui
- Tailwind 4
- NextAuth v5
- Vercel
Start with an empty ledger.
Create a workspace, add your first customer and item, and raise an invoice in a few minutes.