Join our Newsletter — 33% off our NHI Course
Home› FAQ› Architecture & Implementation› How should developers structure a simple Electron expense…
Architecture & Implementation

How should developers structure a simple Electron expense app so income, expense, and total stay in sync as users add entries?

← Back to all FAQ
By NHI Mgmt Group Editorial Team Updated September 26, 2026 Domain: Architecture & Implementation

A practical approach is to keep separate collections for income and expense, then derive the total from those lists each time the UI renders. That keeps the interface simple and avoids storing duplicated calculations. For small desktop apps, local component state can be enough, but validation and a clearer data model become important as the app grows.

Keep the totals derived, not separately maintained

The cleanest way to keep income, expense, and total in sync is to treat the lists as the source of truth and calculate the total from them whenever the interface renders. That avoids drift between stored values and displayed values, which is the main failure mode in small desktop finance apps. If a user edits or removes an entry, the total updates automatically because it is always recomputed from current state.

For a simple Electron app, that usually means storing entry data in one place, then using a deterministic calculation for the balance instead of saving a second “total” field that can become stale. This is especially useful when the app supports inline edits, deletions, or filtered views, because each of those actions can otherwise leave duplicated state out of sync.

A good implementation rule is: if the value can be derived from existing records, do not persist it as primary data. Persisting derived values is only worth it when the dataset is large, the calculation is expensive, or the app needs an audit trail of snapshots rather than a live balance.

Use a simple state shape that matches the user’s mental model

Structure the state around the app’s real entities, such as separate collections for income and expenses, or a single transaction list with a type field if that makes sorting and reporting easier. Either approach can work, but the state should make it obvious how each row contributes to the final balance. The more the data model matches the UI, the less custom bookkeeping you need.

In practice, the safest pattern is to keep the source records normalized and use small helper functions to derive summary values. That gives you a clear separation between data entry, calculation, and presentation, which matters once the app grows beyond a few static inputs. It also makes testing easier because you can verify the calculation logic independently from the UI.

For desktop apps built with local component state, the main trade-off is simplicity versus maintainability. Local state is fine when the app has a single screen and a short lifecycle, but once you add persistence, editing workflows, or shared widgets, a clearer store or reducer pattern usually reduces mistakes.

Update logic should be triggered by state changes, not by manual bookkeeping

Make the total a direct output of the current data, not something users or event handlers must remember to update. When entries are added, edited, or deleted, the rendering path should recalculate the total from the current collections. That keeps the UI consistent even when interactions happen quickly or out of order.

This is where validation and data-model discipline start to matter. You want to prevent malformed entries, negative amounts where they do not make sense, and inconsistent category or type values, because the calculation is only as reliable as the records being fed into it. A simple app can stay lightweight while still enforcing these rules at the point where data enters state.

If the app later adds persistence, exports, or syncing across windows, the same rule still applies: keep one authoritative data structure, then derive any summary views from it. That avoids a common desktop-app bug where one screen updates a total and another screen recalculates from different assumptions.

Risk and Threat Considerations

The main risk in this pattern is not an external attack, it is internal inconsistency caused by duplicated state. If income, expense, and total are stored separately, a missed update can silently produce the wrong balance, which is especially problematic in a finance app where users expect the displayed total to reflect the current record set.

Failure mechanism: A write path updates one value but not the derived total, or multiple UI paths calculate the total differently. Over time, edits, deletions, filtering, and persistence can create drift between what the user sees and what the underlying data actually says.

Impact: Users may make decisions on an incorrect balance, lose trust in the app, or carry forward bad data into exports and reports. In a desktop app, this usually shows up as subtle correctness failure rather than a visible crash.

Standards & Framework Alignment

This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.

OWASP ASVS, CIS Controls v8 and NIST SP 800-53 Rev 5 set the governance and control requirements practitioners need to meet.

FrameworkControl / ReferenceRelevance
OWASP ASVSV2 — Validation and Business LogicCovers input validation and business-rule consistency for transaction calculations.
V15 — Secure Coding and ArchitectureSupports a single-source-of-truth data model and avoidable state duplication.
Recommendation — Validate entry amounts and types before updating derived balances. Design the UI around derived state rather than duplicated summary fields.
CIS Controls v8CIS-16 — Application Software SecurityApplies because the app’s correctness depends on disciplined application logic and state handling.
Recommendation — Review application logic for consistency bugs in shared calculations and state updates.
NIST SP 800-53 Rev 5SA-11 — Developer Testing and EvaluationRelevant for verifying that state changes keep derived totals accurate across workflows.
Recommendation — Test add, edit, delete, and reload paths to confirm the balance is always recomputed correctly.

Practitioner Guidance

What to verify: Test the add, edit, delete, and reload paths with the same fixture data and confirm that the total always matches a fresh recomputation from the source records. If any screen can change entries, it should be impossible for it to bypass the shared calculation path.

Common mistake: Developers often start with a convenient “running total” field and only later discover that it must be updated in several places. For this kind of app, that shortcut is usually more fragile than recalculating on render or from a single derived selector.

Practitioner takeaway: Treat the total as a derived view of the transaction data, not as an independent record, because that is the simplest way to preserve correctness as the UI grows.

Deepen Your Knowledge

Sign up to our weekly newsletter — get 33% off our NHI Foundation Level Course

    NHIMG Editorial Note
    Reviewed and updated by the NHIMG editorial team on September 26, 2026.
    NHI Mgmt Group — the #1 independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org