# Svelte

> Use Fabric.js with Svelte: create the canvas in onMount, turn createDocumentStateStore into a Svelte store, and build undo and save buttons from it.

Source: https://fabricjs-document-engine.jscrate.dev/docs/frameworks/svelte
Last updated: 2026-09-28

A Fabric.js Svelte component creates the canvas in `onMount`, because the `<canvas>` element exists only then. `createDocumentStateStore` already has a `subscribe` method, so turning it into a Svelte store takes one line.

## The component

```svelte
<script lang="ts">
  import { Canvas, Rect } from "fabric";
  import {
    createDocumentEngine,
    createDocumentStateStore,
    type DocumentEngine,
  } from "fabricjs-document-engine";
  import { onMount } from "svelte";
  import { readable, type Readable } from "svelte/store";

  let element: HTMLCanvasElement;
  let engine: DocumentEngine | undefined;
  let state: Readable<ReturnType<ReturnType<typeof createDocumentStateStore>["getSnapshot"]>> | undefined;

  onMount(() => {
    const canvas = new Canvas(element, { width: 800, height: 500 });
    engine = createDocumentEngine({ canvas });
    const store = createDocumentStateStore(engine);

    state = readable(store.getSnapshot(), (set) =>
      store.subscribe(() => set(store.getSnapshot()))
    );

    return () => {
      store.destroy();
      engine?.destroy();
      canvas.dispose();
    };
  });

  function addSquare() {
    engine?.canvas.add(new Rect({ width: 80, height: 60, fill: "#e9c46a" }));
  }
</script>

<div role="toolbar">
  <button on:click={addSquare}>Square</button>
  <button disabled={!$state?.canUndo} on:click={() => engine?.undo()}>
    Undo {$state?.undoLabel ?? ""}
  </button>
  <button disabled={!$state?.canRedo} on:click={() => engine?.redo()}>Redo</button>
</div>
<canvas bind:this={element} aria-label="Drawing canvas"></canvas>
```

## How the store works

`readable(initial, start)` calls `start` when the first component subscribes, and the function it returns when the last one leaves. `store.subscribe` returns exactly that unsubscribe function, so the Svelte store and the engine store stay in sync without extra code.

## SvelteKit

Fabric.js needs a browser. In SvelteKit, `onMount` only runs in the browser, so the Fabric.js Svelte code above is safe during server rendering. If you import Fabric.js at the top of a shared module, move that import into the component.

For saving, add a [storage adapter](https://fabricjs-document-engine.jscrate.dev/docs/storage/storage-adapters) to `createDocumentEngine`. The [plain JavaScript](https://fabricjs-document-engine.jscrate.dev/docs/frameworks/vanilla-js) guide shows the same engine calls without a framework.
