Case Study - One Core, Three Shells: Invoicing Engineered Like Real Software

An offline-first, SARS-compliant invoicing and bookkeeping product for South African small businesses: one Zig core linked into desktop, web and native shells, with integer-cents money and 334 automated tests.

Client
Tekolo
Year
Service
Systems Engineering, Cross-Platform Architecture
Tekolo dashboard showing invoice counts, revenue, outstanding VAT and expenses in rand, with six-month revenue and outstanding-by-client bar charts
Automated tests across Zig and TypeScript
334
Platform shells on one Zig core: shipped, in progress, planned
3
Third-party dependencies in the PDF engine
0
Offline: SARS-compliant with no cloud dependency
100%

Impact

Tekolo is my own product: invoicing and bookkeeping for South African small businesses that works fully offline, satisfies SARS requirements out of the box, and charges no monthly fee. It sits in this portfolio for a specific reason: it is the clearest demonstration that “engineered like real software” is a working method rather than a slogan. There is no client behind it and no data story inside it: just a production codebase, built solo, held to the same standards I bring to client systems.

That standard is concrete. Every monetary value in the system is an integer number of cents on every layer (database columns, Zig structs, JSON wire formats, TypeScript types), so floating-point money errors are structurally impossible. Rounding happens in exactly one place. Invoice totals are computed by the server and only by the server. Compliance rules are enforced where they cannot be bypassed. And 334 automated tests, including contract tests that run the real binary instead of mocks, hold the whole thing together.

Core: money that can’t be wrong

The heart of Tekolo is a Zig core library that owns all business logic, the SQLite database (WAL mode, versioned migrations), and PDF generation. Its money-handling rules are strict: amounts live as integer cents everywhere, and all rounding flows through a single banker’s-rounding function (one boundary, one behaviour, tested directly). When the frontend submits an invoice, the core recomputes every subtotal, VAT line and total itself, ignoring whatever the client sent; a compromised or buggy UI cannot produce a wrong invoice.

South African compliance is enforced at the same depth. VAT is fixed at 15% and validated in both the calculator and the compliance checker, which hard-errors rather than warns. VAT numbers, CIPC registration numbers, bank branch codes and sequential invoice numbering (a SARS requirement) are all validated at the FFI boundary before anything touches the database.

Tekolo invoice form with line items, 15% VAT and server-computed totals
The invoice form: line items, 15% VAT and totals, every figure recomputed server-side in integer cents, whatever the client sends.

The PDF invoices come from a pure-Zig PDF writer with zero third-party dependencies: no headless browser, no C library, just bytes written to the PDF specification.

A SARS-compliant invoice PDF generated by Tekolo's pure-Zig PDF writer
Output of the pure-Zig PDF writer: a SARS-compliant tax invoice, generated by the same core that validated it.
  • Zig
  • SQLite (WAL)
  • TypeScript

Shells: one core, many surfaces

The same Zig core reaches users through multiple shells without forking its logic. On the desktop it compiles to a C ABI static library linked directly into a Tauri 2 (Rust) binary: every call is an in-process function call through extern "C" exports, with no subprocess and no serialisation overhead on the hot path. The Svelte 5 frontend talks to Rust over Tauri IPC; Rust calls straight into Zig.

The same core already compiles to WebAssembly (wasm32-freestanding), the working foundation for a planned browser PWA. A native Linux shell, pure Zig with GTK4 and libadwaita with no webview at all, is in progress. Adding a shell is a deliberate, bounded exercise: the business logic, the database layer and the PDF writer never change.

Whiteboard sketch: one Zig core linked into a Tauri desktop shell, a native GTK4 Linux shell, and a WASM browser PWA
One core, many shells: the Zig library is the single source of truth; each shell is just a surface.
  • Rust / Tauri 2
  • Svelte 5
  • WASM
  • GTK4 (in progress)

Proof: the test story

Tekolo carries 334 automated tests: 106 in Zig covering the core (handlers integration, PDF smoke tests, company isolation) and 228 in Vitest covering the frontend. Five of those are contract tests with no mocks anywhere: they invoke the real Zig CLI, capture its actual JSON output, and assert the TypeScript types against it, so the two sides of the FFI boundary cannot silently drift apart.

CI runs the full gauntlet on every push: Zig tests, Vitest, ESLint, Prettier, a complete Tauri release build, and a security audit. The product has no users yet (it hasn’t launched), and that is the point of showing it: the discipline is the deliverable. This is what my default engineering standard looks like when nobody is watching.

About Tekolo

Tekolo is invoicing and bookkeeping software for South African small businesses: sole traders and small teams who need SARS-compliant invoices, expense capture and VAT tracking without a monthly SaaS fee or a mandatory cloud account. The full local workflow is free and works offline; the roadmap adds a browser PWA and a native Linux app on the same core, with optional paid hosted services only for the things that genuinely cost infrastructure money.

Challenge

The hard part is keeping three languages honest across one boundary, alone. The C ABI surface had to stay frozen through a major Zig upgrade that changed the language’s entire I/O model: solved by constructing the threaded I/O runtime per-call at the FFI edge so external signatures never moved. The Rust shell treats the Zig library as hostile: database paths are canonicalised and prefix-checked against the app data directory, enforced structurally so a Tauri command that skips validation fails to compile. And every shell added must prove it changes nothing beneath it. The moment business logic forks per platform, the one-core thesis is dead.

More case studies

What Drives the Price of Food? Oil, Fertiliser, El Nino and the 2026/27 Squeeze

An interactive analytical study over decades of public data: how oil, fertiliser and El Nino move South African food prices, what Washington does and does not explain, and a dated forecast for 2026/27.

Read more

From Inverter to Impact: Engineering a Continental Solar-Data Platform

A production data platform that unifies 15 inverter ecosystems, processes global solar irradiance in C++, and surfaces fleet carbon impact and O&M health across 24,350 solar plants.

Read more

Tell me about your business challenge

My offices

  • Johannesburg
    South Africa
    2198