This article explains the architectural choices behind Foblex Flow and why the library is designed as Angular-native interaction infrastructure rather than a full graph data platform.
But if you work with Angular, you’ll quickly face a problem:
That’s why we built Foblex Flow — a library that fills this gap.
In this series, we’ll look inside the library — how it works, which principles guide its design, and which architectural decisions make it lightweight and universal.
We’ll start with the foundation: architecture and design principles.

https://github.com/Foblex/f-flow
Most node-based libraries give you everything “out of the box”: a data store, JSON graph, APIs for saving and loading. That’s convenient at first, but becomes a limitation once you try to integrate it into a real application.
Foblex Flow takes a different approach:
📌 In short: the library handles the UI layer, while your application owns the business logic.
That remains the default stateless architecture. Since v19.1, applications can explicitly install the optional Managed Flow State plugin when they want typed graph records, automatic updates for supported gestures, snapshots and undo/redo. The plugin can own generic graph bookkeeping; business meaning and persistence remain application concerns.
The golden rule of the stateless Foblex Flow core: the library never mutates your application-owned data silently.
Every user action is emitted as an Angular event:
This means every action is a signal to your application:
“This happened. You decide what to do.”
That makes the library predictable and easy to integrate with any state management — from Signals to NgRx.
We can break down Foblex Flow into four layers:
The root component (<f-flow>) — coordinates context, events, and canvas state.
The workspace: holds all nodes and connections. Manages zoom, pan, and selections.
Nodes are not predefined components, but directives you can attach to any Angular element.
An SVG path connecting an output to an input. Supports Bezier curves, straight lines, and arrows.
Positions (x, y) are mandatory — without them a node won’t render.
But where and how you store them (Signals, NgRx, Firestore, a plain service) is entirely up to you.
Instead of hiding complexity behind black boxes, the API is transparent: directives and events are explicit.
Foblex Flow works outside the browser.
All window, document, and localStorage references go through DI and can be mocked for SSR.
The library never dictates your persistence strategy.
The diagram illustrates the boundary: Foblex Flow only handles UI state, while your app owns the graph model and business logic.
Managed Flow State is an explicit alternative for the graph-model side of that diagram. It does not move domain rules, validation or persistence into the core, and applications that do not provide it keep the event-driven model unchanged.
The core philosophy: Foblex Flow is not a “platform inside a platform.”
It focuses on what it does best — interactive UI.
This separation makes the library universal. You can build anything — from workflow editors to no-code chatbot builders.
Foblex Flow is not a black box — it’s a transparent tool for building node-based UIs in Angular.
When manual event wiring is unnecessary, provideFFlow(withFlowState()) adds the optional managed graph store without making it a requirement for every editor.
In the next part, we’ll dive into the drag-and-drop engine: