Ledger primitives
Registers, reconciliation, the chart of accounts. One virtualizer, a million rows, byte-identical SSR. Integer minor units — no floats, anywhere.
v0.1.0-beta.2 · MIT · TypeScript · web components + React
Journal entries, server-rendered
A six-posting payroll run, rendered on the server as declarative shadow DOM, adopted at hydration. Zero client re-render. Every color resolves override → role → default.
A register that scales
10,000 entries, one cash account. Fixed row heights make windowing pure arithmetic — no measurement, no layout thrash, the same DOM node count at 100 rows or 100,000.
10,000 entries · … register rows · a seeded fixture, so every visit renders byte-identical data.
Comfortable
Payee and narration stacked — two lines per row.
Compact
One line per row — twice the rows per viewport.
setFilter reshapes rows in place — group summaries recomputed, matches highlighted — while selection and every public index stay in full-data space.
Reconciliation as conflict resolution
Statement lines left, book postings right, matches as tinted pairs. Accept or reject from the gutter, like a merge conflict. Reconciled means exactly zero — integer arithmetic, no epsilon.
Hover or tap a matched pair to accept or reject it, or accept every exact match at once. Matching is deterministic — exact 1:1 pairs plus bounded sum matches — read the matching engine docs.
| Indicator | State | Description |
|---|---|---|
proposed | Suggested by the matching engine — accept or reject | |
accepted | Cleared against the statement | |
outstanding | In the books, not yet presented to the bank | |
missing | On the statement, no book entry — create one |
Every edit, diffed like code
Two versions of one entry as an audit-trail diff — word highlights, pill adds, postings aligned by account and currency with exact before/after amounts. Server-rendered, like every card on this page.
Both versions balance to exactly zero. The diff is pure data from diffEntryVersions.
The chart of accounts as a tree
Assets:Current:Cash-Maybank materializes into a keyboard-navigable tree — rolled-up balances, status dots. A file tree with git status, for accounts.
250 entries · rolled-up balances · status dots via setAccountStatus() · search expands ancestors of every match and restores the previous expansion on clear.
Expanded
Every status dot sits on the account that owns it.
Status roll-up
Collapsed groups inherit the highest-severity descendant status.
Honest about imbalance
Postings that don't sum to zero per currency are flagged with the exact residual. Never repaired, never hidden.
The cash leg is exactly RM 1.00 short — rendered, flagged, left alone.
Built at Cynco
Accounting infrastructure built like a database: integer minor units end to end, entries balanced by construction, rendering that holds at a million rows. The primitives under everything we ship.
The whole idea, in ninety seconds
An entry posts, sums to exactly zero, and rolls up the chart of accounts. Every frame rendered from the same integer minor units the engine stores — no mockups, no recordings.
Driven by @remotion/player's frame clock — the numbers on screen are the data.