Nodos Plugins: The Real-Time Graph That Refuses to Sleep

How a schema-driven plugin system, GPU-first execution, and always-dirty nodes turn Nodos into a live media engine instead of a static dependency graph.

8 min read • View on GitHub • More from nodos-dev

A wide control room scene shows a dependency graph built like clockwork, with most gears resting until a few special nodes keep turning. A clock, input device, and video source feed a GPU pipeline, explaining how a real-time graph can mix event-driven updates with continuous execution.
Some nodes only wake up when dependencies change. Others have to run every frame, or the whole system loses time, input, and motion.
Key Takeaways

The graph that cannot go idle

A normal reactive graph waits for change. Nodos cannot always afford to wait. Some nodes have to wake up every frame even when nothing upstream moved, because time, input, GPU state, and streaming media do not politely stop for dependency checks.

That is the point of the AlwaysDirty idea. It says some parts of the graph are not event handlers. They are part of the engine’s heartbeat. Without them, clocks stall, animations freeze, live sources drift, and frame history goes stale.

The core trick is simple to say and hard to design well. Some nodes are reactive. Some must run continuously to keep a real-time graph alive.

ModelExecution modelDiscoverySchema enforcementGPU integrationBest suited for
Reactive graphRuns only when dependencies changeUsually hard-coded or localLoose or optionalOften secondaryDataflow that can sleep
Generic plugin folderExtends a host app by conventionManual registration or scanningMinimalDependent on hostSimple extension ecosystems
Nodos pluginsMixes reactive and always-dirty executionRuntime plugin export contractFlatBuffers-backedCentral to the designLive media, compositing, and interactive graphics

What lives in the plugin standard library

The repository is organized less like a grab bag and more like a toolkit. nosAnimation handles time and interpolation. nosCompositing handles layers and layouts. nosFilters covers image processing. nosFlow handles control flow. nosExperiment is where the team pushes on the edges.

A close editorial scene presents several labeled plugin toolkits arranged on a workbench, each one shaped for a different task. One kit is built for timing, another for layering images, another for filters, and another for control flow, showing that the repo is a standard library rather than a pile of unrelated extensions.
The repo packages the recurring jobs a real-time engine needs, so plugin authors can build against a shared vocabulary instead of inventing every part from scratch.
Plugin areaWhat it contributesWhy it matters
nosAnimationKeyframes, interpolation, timing behaviorKeeps motion consistent across frames
nosCompositingLayering, layout, text renderingTurns raw assets into a usable scene graph
nosFiltersBlur, correction, temporal effectsMakes GPU processing feel like a first-class feature
nosFlowLoops, triggers, conditional executionLets the graph act like a program, not just a pipeline
nosExperimentPrototype and stress-test nodesProvides room for the runtime to evolve

How a node becomes executable

The plugin entrypoint is a contract. A plugin exports its node functions through nosExportPlugin, and those functions are registered with helpers such as RegisterAnimate. The engine does not need to know the plugin’s private structure. It only needs the exported shape.

The main idea of Nodos is to provide a complete, opinionated solution for building web applications, without the need to make hundreds of decisions about libraries and architecture.

Kirill Mokevnin, Creator of Nodos, Co-founder of Hexlet · Nodos: a new web framework

The schema-first trick

The discipline comes from the schemas. Node and pin data live in .fbs FlatBuffers files, which makes the contract explicit and portable. Editor, runtime, and serialization all speak the same shape.

That matters more than it sounds. A visual engine gets messy fast when UI definitions, runtime code, and persistent data drift apart. Schema-first design reduces that drift. It also makes refactoring safer because the shape of a node is not hidden inside one language boundary.

ApproachWhere node shape livesWhat tends to breakLong-term effect
Ad hoc C++ structsIn implementation filesEditor and runtime slowly divergeTight coupling, brittle evolution
Schema-first FlatBuffersIn shared .fbs definitionsCompiler catches mismatches earlierStable contracts across tools
Loose JSON conventionsIn docs and implicit code pathsSerialization edge casesEasy to start, hard to trust

GPU state, time, and frames in motion

Two files make the runtime philosophy visible. AnimateNode turns elapsed time into normalized motion, with support for swing looping and variable step timing. TemporalBlurNode keeps frame history alive and updates texture formats when the input changes.

// Conceptual shape of the execution
float t = elapsedSeconds / duration;
if (swing) {
  t = pingPong(t);
}
if (variableStepTiming) {
  t = smoothWithFrameDelta(t, deltaTime);
}

history.push_back(currentFrame);
if (inputResolutionChanged) {
  UpdateTextureFormat();
}
nosVulkan->RunPass(TemporalBlurShader, history);

This is where the repo stops looking like a plugin directory and starts looking like infrastructure. It is not just describing effects. It is preserving state, timing, and GPU continuity under live conditions.

Generating illustration...

The contract is not just conceptual. A schema becomes a registered node, and the engine can execute it without knowing its private implementation.

Why this feels like infrastructure, not a plugin pack

A lot of plugin systems are permissive. This one is opinionated. It assumes a serious runtime, a specific execution model, and a team willing to encode stability into the architecture instead of patching it later.

That is why the repo feels mature. The refactoring breadcrumbs, the compatibility-minded naming, the split between shared types and plugin logic, and the emphasis on GPU-aware execution all point to the same thing: this is not a demo architecture. It is the scaffolding for live production work.

QuestionOrdinary extension systemNodos plugins
Does the engine keep time itself?Not necessarilyYes, through always-dirty execution
Can plugins be discovered cleanly?Sometimes, by conventionYes, through a formal export contract
Do data shapes stay consistent?Only if developers stay carefulYes, through shared schemas
Does GPU state matter?Often treated as downstream detailIt is part of the core design