Architecture overview
JasperNode is deliberately small. Everything in the product is one of three components arranged around a single data structure. Understand those three and you understand the system.
Three components around one data layer
Section titled “Three components around one data layer”- The Tag Engine — the data layer. One in-memory tree of tags with publish/subscribe on every value change, persistence, and optional history. It owns no I/O of its own.
- Logic execution — scripts that compute tag values. Today this is the Logic Cycle (event-driven, reactive). A time-driven High Performance Cycle is on the roadmap.
- Connectors — readers and writers at the edges of the data layer. They are the only things that talk to the outside world (fieldbuses, networks, clouds, and built-in services).
Every component lives at the perimeter of the Tag Engine and talks to it the same way: by subscribing to tags and writing tags. Nothing reaches around the engine.
Browser IDE AI agent (JasperX cloud) │ │┌────┴───────────────────────────────────────┴────┐│ System connectors │ IDE · JX · Persist · Tools · Logic Cycle└───────────────────────┬──────────────────────────┘ │ subscribe / write┌────────────────────────┴───────────────────────────┐│ TAG ENGINE │ one in-memory tag tree│ pub/sub · history · persistence │└───┬───────────────┬───────────────┬─────────────────┘ │ │ │┌───┴────┐ ┌───┴────┐ ┌───┴────┐│ OT │ │ OT │ │ IT │ …│ Modbus │ │ S7 │ │ MQTT │└───┬────┘ └───┬────┘ └───┬────┘ │ │ │ field field brokerThis is why the model is easy to reason about: the IDE, the AI agent, the logic cycle and every connector are all just participants that read and write tags. There is no privileged side channel.
The data layer
Section titled “The data layer”The Tag Engine holds every value in memory and notifies subscribers the instant a value changes. Internally it keeps two value planes (one optimised for the TypeScript side, one for the native side) joined by a change ring that delivers updates in order; in practice you never see this — you see tags, values and subscriptions. What matters to you:
- Publish/subscribe on change. Subscribe to a tag, a path, or a wildcard pattern and you receive every change. The IDE, connectors and the logic cycle are all subscribers.
- Change suppression. Writing the same value again (after rounding to the tag’s configured decimals) produces no event — the engine only emits real changes.
- One source of truth. There is no second place where state lives. Configuration, runtime status and live values are all tags.
Details: Everything is a tag.
Logic execution
Section titled “Logic execution”Scripts are treated as just another participant around the engine. The shipping executor is the Logic Cycle:
- Event-driven. It sleeps until a value that a script depends on changes, wakes, runs exactly the scripts whose triggers fired, then parks again. A one-second safety net bounds any missed wake-up.
- Isolated. Because scripts are user-written code, the Logic Cycle runs in its own sandbox separate from the engine, with a watchdog that aborts any run exceeding 30 seconds. A runaway script cannot freeze the data layer.
A deterministic, sub-millisecond High Performance Cycle (compiled, time-driven) is designed for but not included in the current release. See Logic & the Logic Cycle.
Connectors at the perimeter
Section titled “Connectors at the perimeter”A connector bridges the tag tree to exactly one external surface. Connectors come in three kinds
— ot (physical buses), it (networks/clouds), and system (built-in services) — and never depend
on each other. Each instance owns a small, predictable set of tags for its configuration, its enable
switch, and its live status. See Connectors.
Where work runs, and how faults are contained
Section titled “Where work runs, and how faults are contained”A single bad connector must never take down the node. JasperNode achieves that by running components in separate places and isolating failures to one connector type at a time:
| Runs in… | Components | If it fails… |
|---|---|---|
| Main runtime | Tag Engine, IDE, JX (cloud bridge), Persist, Tools | hardened first-party code; shares the core process |
| Its own sandbox | The Logic Cycle (your scripts) | a script crash or timeout is caught; the engine is fine |
| One worker per connector type | Network/cloud connectors: MQTT, InfluxDB, Modbus Server, HMI, JasperMate | a fault stops that type’s worker only; other types run on |
| A native thread per type | Rust fieldbus connectors: Modbus, Serial, EtherCAT, S7 | a panic is trapped per instance; siblings keep running |
On top of this, in-process fieldbus connectors auto-roll-back: repeated crashes shortly after a change cause the runtime to restore the last-known-good version on the next restart and tell you what was rolled back and why. The engine and the rest of your connectors stay up throughout.
Services above the engine
Section titled “Services above the engine”A few responsibilities don’t fit the “reads and writes tags” shape — they are stateless coordination or policy. These live as services beside the engine, not as connectors:
- Deploy Gate — the test-before-deploy state machine that gates AI-driven (and, in commissioning/ production, human) changes and records the audit trail.
- AI Rule Registry — hard guardrails every AI action passes through (for example: read a script before modifying it; refuse to delete a tag that has active subscribers).
- Chat bus — routes chat between the IDE and the AI agent.
See The AI agent & Deploy Gate.
Persistence and history
Section titled “Persistence and history”JasperNode is an in-memory system that writes through to a single local SQLite database:
- Tag values are flushed in a batched transaction every 250 ms.
- Tag properties (description, script code, triggers, …) are written per change — and also streamed to the IDE in real time.
- Memory-only tags (
isMemoryTag) are never persisted — the equivalent of non-retentive memory. - Per-tag history keeps the previous value by default and can opt in to as many as 1000 recent entries for trends and debugging.
- If disk writes fail, the runtime keeps running on its in-memory state — availability first.
Only the user-editable subtree (__sys/node/user/**) is included in project backup and restore;
everything else is regenerated by the receiving node. See System tags.
The whole node in one tree
Section titled “The whole node in one tree”Because configuration and status are themselves tags, the node is fully described by its tag tree:
your application data in user space, and a structured __sys/ tree for host info, node identity,
connector config and status, engine statistics and logs. That uniformity is what lets one IDE — and
one AI agent — see and operate the entire system through a single interface. See
System tags for the map.