Skip to content
D
Documentation

Qwik quick start

tutorial
2 min readUpdated

Mount a 400-pixel-high diagram with two connected nodes, keep edits in serializable signals, and use the live instance from a Fit view button.

Framework bindings are thin skins over one headless model: specs describe your intent, live models hold the data, and the engine owns behavior.

Prerequisites

Use an existing Qwik 1.x application with @builder.io/qwik satisfying ^1.5.0 and @grafloria/element satisfying ^0.5.0; see the JavaScript quick start for the shared engine and renderer prerequisites.

Keep your application's Qwik Vite configuration: no Grafloria-specific Vite plugin is required. This example runs in a server-rendered Qwik City application; the binding creates its live diagram in a browser-only task at document ready.

1. Install the binding and its peers

Run this in your application directory:

bash
npm install @grafloria/qwik @grafloria/engine @grafloria/renderer @builder.io/qwik@^1.5.0 @grafloria/element

The Qwik package re-exports the shared spec types, so the component and its data types use one import site.

2. Mount a controlled canvas

Bind Qwik signals to GrafloriaFlow rather than React state; see the React quick start for the shared NodeSpec and EdgeSpec canvas setup.

The signals contain only plain data. Both change callbacks are QRLs created with Qwik's $(): they return the edited specs to the signals bound to nodes and edges.

onInit$ gives you the mounted DiagramInstance. Keep it in a signal marked with noSerialize() rather than asking Qwik to serialize a live renderer. The button uses that instance's fitView() to frame the content.

tsx
import { $, component$, noSerialize, useSignal, type NoSerialize } from '@builder.io/qwik';
import {
  GrafloriaFlow,
  type DiagramInstance,
  type EdgeSpec,
  type NodeSpec,
} from '@grafloria/qwik';

export default component$(() => {
  const nodes = useSignal<NodeSpec[]>([
    {
      id: 'extract',
      position: { x: 80, y: 120 },
      size: { width: 180, height: 72 },
      label: 'Extract',
    },
    {
      id: 'load',
      position: { x: 380, y: 120 },
      size: { width: 180, height: 72 },
      label: 'Load',
    },
  ]);
  const edges = useSignal<EdgeSpec[]>([
    {
      id: 'extract-load',
      source: 'extract',
      target: 'load',
      sourceHandle: 'right',
      targetHandle: 'left',
    },
  ]);
  const instance = useSignal<NoSerialize<DiagramInstance>>();

  return (
    <section>
      <button
        type="button"
        disabled={!instance.value}
        onClick$={() => instance.value?.fitView(40)}
      >
        Fit view
      </button>
      <GrafloriaFlow
        nodes={nodes.value}
        edges={edges.value}
        fitView
        onNodesChange$={$((next: NodeSpec[]) => {
          nodes.value = next;
        })}
        onEdgesChange$={$((next: EdgeSpec[]) => {
          edges.value = next;
        })}
        onInit$={$((diagram: DiagramInstance) => {
          instance.value = noSerialize(diagram);
        })}
        style={{ height: '400px' }}
      />
    </section>
  );
});

The canvas draws Extract and Load side by side, with an edge from Extract's right port to Load's left port. fitView frames the initial content. The Fit view button stays disabled until onInit$ supplies the instance.

Extract and Load appear side by side with a right-pointing connecting arrow. The Fit view button sits above the canvas.

3. Run and edit the diagram

Start your Qwik application's development server:

bash
npm run dev

Open the address printed by your application. Drag either node and use Fit view to frame the diagram again. The binding projects node and edge change events into specs for your callbacks; changes to the controlled arrays feed back into the mounted instance through setNodes() and setEdges().

You now have a sized, editable canvas, controlled node and edge state, and instance access for your own controls. The binding disposes its diagram and removes its event subscriptions on unmount; do not dispose it in onInit$.

Choose the state owner

Keep nodes, edges, and their change callbacks when your application owns the specs. For an uncontrolled canvas, use defaultNodes and defaultEdges instead: they seed the diagram at mount, rather than supplying ongoing controlled updates.

For more on serializable state and live objects, see Qwik: state and resumption. For canvas sizing, see Theme a canvas.

Where next

Was this page helpful?