Menu

Integration

The chart widget is framework-agnostic. You create it with pure JavaScript, then mount it using a thin adapter for your framework. Switching frameworks later means changing 3 lines of mounting code — the chart stays the same.

Flitter Chart works with React, Svelte, and vanilla JavaScript.

React

Install

npm install @flitterjs/adapter-react flitterjs
npx @flitterjs/cli@latest add bar-chart

The first command installs the rendering engine and React adapter. The second generates the chart source code directly into your project.

Usage

import Widget from "@flitterjs/adapter-react";
import BarChart from "./charts/bar-chart";
 
function MyChart() {
  const chart = BarChart({
    title: "Monthly Revenue",
    data: {
      labels: ["Jan", "Feb", "Mar", "Apr"],
      datasets: [
        { legend: "Revenue", values: [40, 65, 50, 80] },
      ],
    },
  });
 
  return <Widget widget={chart} width="100%" height="400px" />;
}

Props

PropTypeDefaultDescription
widgetWidget—The Flitter widget to render
widthstring"100%"Container width (CSS value)
heightstring"300px"Container height (CSS value)
renderer"svg" | "canvas""svg"Rendering backend

How It Works

The Widget component creates a container div with the specified dimensions and mounts an SVG or Canvas element inside it. It uses AppRunner from flitterjs to drive the render loop and automatically handles resizing.

View React Widget source
import { useEffect, useRef } from "react";
import { type Widget, Alignment, AppRunner, Container, Text } from "flitterjs";
 
type WidgetComponentProps = {
  widget?: Widget;
  width?: string;
  height?: string;
  renderer?: "canvas" | "svg";
};
 
function WidgetComponent({
  width = "100%",
  height = "300px",
  renderer = "svg",
  widget = Container({
    width: Infinity,
    height: Infinity,
    alignment: Alignment.center,
    child: Text("Hello World"),
  }),
}: WidgetComponentProps) {
  const containerRef = useRef<HTMLDivElement | null>(null);
  const ref = useRef<SVGSVGElement | HTMLCanvasElement | null>(null);
 
  useEffect(() => {
    const runner = new AppRunner({
      view: ref.current!,
      window: window,
      document: document,
    });
    runner.runApp(widget);
    runner.onMount({ resizeTarget: containerRef.current! });
 
    return () => { runner.dispose(); };
  }, [widget, renderer]);
 
  return (
    <div style={{ width, height }} ref={containerRef}>
      {renderer === "canvas" ? (
        <canvas style={{ width: "100%", height: "100%" }} ref={ref} />
      ) : (
        <svg style={{ width: "100%", height: "100%" }} ref={ref} />
      )}
    </div>
  );
}
 
export default WidgetComponent;

Svelte

Install

npm install @flitterjs/adapter-svelte flitterjs
npx @flitterjs/cli@latest add bar-chart

The first command installs the rendering engine and Svelte adapter. The second generates the chart source code directly into your project.

Usage

<script>
  import Widget from "@flitterjs/adapter-svelte";
  import BarChart from "./charts/bar-chart";
 
  const chart = BarChart({
    title: "Monthly Revenue",
    data: {
      labels: ["Jan", "Feb", "Mar", "Apr"],
      datasets: [
        { legend: "Revenue", values: [40, 65, 50, 80] },
      ],
    },
  });
</script>
 
<Widget widget={chart} width="100%" height="400px" />

Props

PropTypeDefaultDescription
widgetWidget—The Flitter widget to render
widthstring"100%"Container width (CSS value)
heightstring"300px"Container height (CSS value)
renderer"svg" | "canvas""svg"Rendering backend
ssr{ size: { width, height } }?undefinedEnable server-side rendering with fixed dimensions

Server-Side Rendering

The Svelte integration supports SSR out of the box using linkedom:

<Widget
  widget={chart}
  width="600px"
  height="400px"
  ssr={{ size: { width: 600, height: 400 } }}
/>
View Svelte Widget source
<script lang="ts">
  import { onMount } from "svelte";
  import { parseHTML } from "linkedom";
  import { type Widget, Alignment, AppRunner, Container, Text } from "flitterjs";
  const browser = typeof window !== "undefined";
 
  export let renderer: "svg" | "canvas" = "svg";
  export let widget: Widget = Container({
    width: Infinity, height: Infinity,
    alignment: Alignment.center,
    child: Text("implement widget here"),
  });
  export let ssr: { size: { width: number; height: number } } | undefined = undefined;
  export let width = "100%";
  export let height = "300px";
 
  let renderEl: SVGSVGElement | HTMLCanvasElement;
  let containerEl: HTMLElement;
  let runner: AppRunner;
  let innerHTML: string = "";
 
  if (!browser) {
    const { document: _document, window: _window } = parseHTML("<svg></svg>");
    const _svg = _document.querySelector("svg")!;
    runner = new AppRunner({ view: _svg, window: _window, document: _document, ssrSize: ssr?.size });
    innerHTML = runner.runApp(widget);
  }
 
  $: { [mounted, widget, runner]; rerender(); }
 
  let mounted = false;
  onMount(() => {
    mounted = true;
    runner = new AppRunner({ view: renderEl, window, document, ssrSize: ssr?.size });
    renderEl.innerHTML = "";
    runner.onMount({ resizeTarget: containerEl });
    return () => { runner.dispose(); };
  });
 
  const rerender = () => {
    if (!browser || !mounted || !runner) return;
    runner.runApp(widget);
  };
</script>
 
<div bind:this={containerEl} style="--width: {width}; --height: {height}">
  {#if renderer === "canvas" && browser}
    <canvas class="flitter" bind:this={renderEl} />
  {:else}
    <svg class="flitter" bind:this={renderEl}>{@html innerHTML}</svg>
  {/if}
</div>
 
<style>
  div { width: var(--width); height: var(--height); }
  .flitter { width: 100%; height: 100%; }
</style>

Vanilla JavaScript

No framework? Use AppRunner directly.

Install

npm install flitterjs
npx @flitterjs/cli@latest add bar-chart

The first command installs the rendering engine. The second generates the chart source code directly into your project.

Usage

<div id="chart-container" style="width: 600px; height: 400px;">
  <svg id="chart" style="width: 100%; height: 100%;"></svg>
</div>
import { AppRunner } from "flitterjs";
import BarChart from "./charts/bar-chart";
 
const chart = BarChart({
  data: {
    labels: ["Jan", "Feb", "Mar", "Apr"],
    datasets: [
      { legend: "Revenue", values: [40, 65, 50, 80] },
    ],
  },
});
 
const svg = document.getElementById("chart") as SVGSVGElement;
const container = document.getElementById("chart-container") as HTMLElement;
 
const runner = new AppRunner({
  view: svg,
  window: window,
  document: document,
});
 
runner.runApp(chart);
runner.onMount({ resizeTarget: container });
 
// Clean up when done
// runner.dispose();

Canvas Renderer

Switch to Canvas by using a <canvas> element instead:

<div id="chart-container" style="width: 600px; height: 400px;">
  <canvas id="chart" style="width: 100%; height: 100%;"></canvas>
</div>
const canvas = document.getElementById("chart") as HTMLCanvasElement;
const runner = new AppRunner({
  view: canvas,
  window: window,
  document: document,
});
runner.runApp(chart);
runner.onMount({ resizeTarget: container });

SVG vs Canvas

FeatureSVGCanvas
DOM integrationFull DOM nodes, inspectableSingle element
Performance (few elements)GoodGood
Performance (many elements)DegradesBetter
Text renderingNativeRendered
SSR supportYes (Svelte)No

Recommendation: Use SVG (default) unless you have performance issues with large datasets, then switch to Canvas.