Skip to main content
Every jq expression a flow carries — a node’s expression, a branch or loop condition, a binding’s injection or update jq — is authored in one field two ways: by typing jq into the field’s resting text control, or in a visual editor, opened from that control, that draws the expression as a small, editable node graph and writes it back as jq. The wire always carries the jq text. That visual editor is not a flow-only thing and not a plugin you install. It is jq-studio — the platform’s open-source, built-in jq editor. The Studio SDK re-exports its JqField component, the Studio host injects the design system and installs the evaluation worker, and the flow editor renders that field directly. The same editor serves every jq field on every Studio surface — a host field, another plugin’s field, a flow’s field — with nothing to register and no gating.
The editor itself — its node vocabulary, the faithfulness guarantee, the theming contract, and the worker model — is documented with jq-studio and in its open-source repository. This page covers what is specific to authoring a flow: the field’s tabs and what each field seeds the editor with.

Inline or Template

A jq field in the flow editor is a two-tab control — Inline and Template — and the two are mutually exclusive: the wire carries exactly one.
  • Inline is the SDK’s JqField: a resting text control holding the jq, plus a Visual editor button that opens the visual canvas in a modal dialog. Edit the jq as text in the control, or open the dialog to build it as a node graph; on save the dialog writes the jq back to the same control. A description and an error helper slot render under the control, wired to it for screen readers.
  • Template picks a stored template and edits its kwargs through a schema-assisted form.
The active tab follows the draft: a field that already holds a template opens on Template, otherwise on Inline. There is no separate “Editor” tab and no auto-open of the canvas — the visual editor is always reached from the Inline control’s Visual editor button. Switching tabs is a mode change that clears the mode you leave, after a confirm when it holds data. Inside the visual editor, a loaded expression is drawn as a graph only when it round-trips faithfully back to your exact jq. An expression the editor cannot draw keeps your text verbatim and shows it with a neutral notice — your jq is never altered — and the editable canvas is then reached only through an explicit Start empty. That fallback lives inside the dialog; it is not a tab. See the jq editor for the canvas itself.

What each field seeds

Every jq field names what . is at its site, so the editor’s Test panel seeds a sample of the right input shape and — where the engine exposes a matching validator — the Validate action checks the right shape server-side:
  • a node expression and a conditional or branch condition see the node envelope — the run’s inputs and the upstream nodes’ outputs, with this node’s .result still null (a condition must return true or false);
  • an on-error condition or expression sees the error envelope — the failed node’s error on .upstream_outputs (.error, .error_type, .error_kind, .additional);
  • a node’s return expression sees the narrow return namespace — only .result, .outputs, .flow_graph_kwargs, and .states; here .upstream_outputs is a hard build error, not a null;
  • a binding’s input injection jq runs after the node’s input is assembled, before the node runs: a template input program sees the record (. is the subject’s document at the attach path) with its declared params bound as the single object $params; a custom injection sees {record, input}.record the bound record, .input the node’s input so far — and its value is placed into the input at the injection’s into field;
  • a binding’s update jq runs after the node completes: a template update program sees {record, input}.record the bound record, .input the adapter’s output — and a custom update sees {record, output, input} (.output the node’s output, .input its input); either returns a template-relative op batch ([{op, path, value}]), and a per-op compare-and-set guard rides an op as {path, expected};
  • an update’s adapter jq sees {output, input} — the node’s output and input — and returns the named update program’s declared input object;
  • a binding’s subject and scope expressions see the bare flow inputs document (. is flow_graph_kwargs, with no envelope);
  • a loop’s while condition sees the node envelope with .iterate present.iterate.item is always null there, while .iterate.prior_outputs holds the per-iteration results the condition tests;
  • a loop’s foreach expression and a string loop count see the node envelope — for a foreach driver .iterate is the enclosing loop, not this one; a count runs jq only when the count is a string (a literal number bypasses it);
  • a map item argument sees the loop-body envelope, where .iterate.item is the current item (never null here) and .iterate.iteration its zero-based position.

Autocomplete from a state’s template jq

A jq field that can reach a bound state offers autocomplete from the template jq of the templates attached to that state. Typing offers each purpose: "input" template jq by name and inserts its call handle — tjq_<name>({…}), or tjq_<template>__<name>({…}) when a name is shared across the state’s attachments — so an expression reads a template’s value through the prelude without hand-writing the def. The suggestions come from the served state-template document’s template_jq for the bound state’s templates, so they track whatever the attachment declares.

See also

  • The jq editor — jq-studio, the built-in editor the flow editor renders, and how to embed it in your own app.
  • The visual jq editor — the editor as it appears in the flow canvas: its node vocabulary, the faithfulness guarantee, and the editor shell.
  • Babelfish Flows — the flow engine whose fields author through this editor.
  • Author a Studio plugin — the SDK re-export every plugin field renders the same editor from.