Skip to main content

Working with Streams

Kelp is an implementation of the reactive programming paradigm as a visual dataflow language. Each app built in Kelp is a graph of functional components and wires between them.

A wire is a stream of events. Events are containers that hold and transfer data between components. Kelp has two event types: data events and signals. When we mention "events" in the Kelp documentation, we mean data events in most cases.

Data Events

Data events can hold and transfer simple constants, arrays, objects, HTTP requests, and other JSON documents. As a data structure, the data inside any event is a JSON object.

data event structure

Components in Kelp receive and emit events through wires and then perform specific actions.

You can transform or filter data events and signals by applying transformation functions ("transformations" for short). You apply a transformation to a wire and choose one of the transformation languages Kelp supports: KelpQL, JMESPath, JSPath, and other special types of transformations. Learn more about data transformations.


Signals are special control events that help to manage the execution flow of an app. Signals change the default operations of components by providing instructions to them.

Signals travel through wires with data events. Like data events, signals are JSON objects.

Note: Kelp can transform signals to and from regular data events.


Some components emit signals by default. For example, the HTTP component emits the BEFORE_LOAD signal before it sends a response and later emits the AFTER_LOAD signal after it sends a response.

To control the data flow, you may need to add signals yourself. To do so, use the Signal or Inject Signal components.

Unlike events, signals have unique properties. Some signals like SCOPE_CHANGED can pass through components without being stopped or consumed. Others like RESET can impact the operation of components and component's ports.

At the moment, Kelp supports the following signals:

  • RESET signals a full reset of an app, component, or group of components. Widgets receiving RESET are completely re-rendered.
  • SCOPE_CHANGED signal means a partial reset or change of data scope. Widgets can reset their state, but won't trigger a full re-rendering.
  • PROGRESS signals the completion status of some long-running processes. You can also provide a percent of completion. Widgets react to this signal by displaying a progress bar.
  • CUSTOM_ERROR signals an expected exceptional situation. For example, the HTTP component sends this signal for 400 type of status codes (for example, 403 Forbidden or 404 Not Found).
  • UNKNOWN_EXCEPTION signals an unexpected exceptional situation. For example, the HTTP component sends this signal for 500 type of status codes in response.
  • BEFORE_LOAD signal marks the beginning of an async operation. For example, the HTTP component sends this signal when the HTTP request is sent, but before the response is received. Widgets react to this signal by displaying a progress bar.
  • AFTER_LOAD signal marks the end of an async operation. Widgets react to this signal by completing and hiding a progress bar. BEFORE_LOAD and AFTER_LOAD usually go one by one. If a widget received one signal but didn't receive another, the widget's progress bar will freeze and turn amber to signal an abnormal completion of async operation.

See also