Skip to main content
The Studio authors every jq expression through a visual editor: a small, editable node graph that reads and writes the jq text on the wire. That editor is jq-studio — an open-source, Apache-2.0 project. It is the Studio’s built-in editor, and it is a standalone library you can embed in any app of your own.
jq-studio is developed in the open at github.com/tai42ai/jq-studio and published to npm as @tai42/jq-studio (Apache-2.0). Its full component reference — the node vocabulary, the faithfulness guarantee, the theming contract, and the worker model — lives in that repository. This page covers how the Studio ships it and how to embed it; it does not restate the editor’s own docs.

Built in, everywhere

The Studio SDK re-exports jq-studio’s JqField component and its declaration types. The Studio host does two things once, at the shell level, so the editor is available to every field:
  • it injects the Studio’s design system through a PrimitivesProvider, so the editor renders in the host’s own inputs, buttons, and tokens rather than a bundled look; and
  • it installs the editor’s single evaluation worker — one dedicated Web Worker shared across the page — so jq evaluation runs off the main thread for every field.
Because the host does this, a jq field never installs, registers, or gates the editor. A host field — an access-control policy condition, a hook condition or expression — offers the canvas, a plugin field offers it, and a flow’s jq field offers it, all from the one re-export. There is no “is an editor present?” conditional and no provider to opt into: the editor is part of the SDK, so a field that renders JqField gets the visual canvas by construction.

From the schema, with no code

A form does not have to name its jq fields at all. SchemaForm reads the x-tai42-expression annotation the server puts on a jq-typed string property and renders JqField for it — the resting control plus the visual-editor door — carrying the annotation’s label, blurb, input keys, and Test-panel sample straight onto the field. So the server decides which properties are expressions, and every form over that schema agrees. The door is code-split. SchemaForm reaches the editor through a dynamic import behind a lazy boundary, taken only when a field actually carries a well-formed annotation — a form with no expression fields never pulls the editor, its worker, or its wasm into the bundle. A malformed annotation, or a language this client does not know, degrades silently to the ordinary text input rather than throwing.

A standalone library

@tai42/jq-studio embeds in any React app the same way the Studio uses it: render JqField inside a PrimitivesProvider that supplies your design-system primitives.
The editor themes itself entirely through CSS custom properties. Every color it paints reads from a --jq-* custom property, and it inherits light or dark from the nearest ancestor carrying a data-theme attribute — so an app themes the editor by setting those properties on a wrapper, with no editor configuration of its own. See jq-studio’s repository for the full --jq-* contract and the primitives interface.
The editor evaluates jq in a same-origin Web Worker and enforces a terminate-on-deadline, so a runaway expression is killed rather than left to hang the tab. The worker is a real, same-origin file — a 'self' worker with 'wasm-unsafe-eval', which is what a strict Content-Security-Policy permits. The Studio’s own policy already allows it; an embedding app grants the same policy to run evaluation off-thread.

See also