LearnTroubleshootingMigrate to v1

Migrate to Svelte Flow 1.0

Migration Guide

nodes & edges are now using $state.raw instead of writable

Svelte 5 introduces runes which are now getting used for nodes and edges.

Old API

const nodes = writable([...]);
const edges = writable([...]);

New API

let nodes = $state.raw([...]);
let edges = $state.raw([...]);

Updating Nodes & Edges

Previously it was possible to update single node properties. Theoretically, this would also be possible with $state, however the performance implications of this are unfortunately too great, so we opted to using $state.raw.

This means that nodes and edges are to be treated as immutable from now on. If you are making updates manually make sure you:

  1. create a new node/edge object, when updating a property.
  2. reassign the nodes/edges array (this was technically required before anyway)

nodes & edges need to be bound from <SvelteFlow />

Old API

<SvelteFlow {nodes} {edges} />

New API

<SvelteFlow bind:nodes bind:edges />

Custom Node & Edge Props

This is by enlarge a general change in Svelte 5 but it does have quite a big impact on typing the props of Custom Nodes & Edges.

Old API

// CustomNode.svelte
 
type $$Props = NodeProps;
 
export let data: $$Props['data'];
export let position: $$Props['position'];
export let selected: $$Props['selected'];

New API

let { data, position, selected } : NodeProps = $props();

Hooks

Hooks now return reactive values instead of writables. Because $state values cannot be returned by functions directly we have to return an object with a .current property to keep reactivity. In this regard, we are following the official trend set by the Svelte library authors.

Old API

const edges = useEdges();
$: console.log(edges);

New API

const edges = useEdges();
$inspect(edges.current);

Note that in case of useNodes, useEdges and useViewport reassignments to .current work!

const nodes = useNodes();
 
function updateNodes() {
   nodes.current = [...]
}

useSvelteFlow

useSvelteFlow provides access functions that operate on the internal state. When using the hook inside descendants of the <SvelteFlow /> component (probably custom nodes/edges), apart from changes to some of the functions it exports there is nothing you have to change.

// CustomNode.svelte
 
const { updateNode, screenToFlowPosition } = useSvelteFlow(); //still works

However, if you are using the <SvelteFlowProvider /> to extend the scope of internal store to components outside of the main <SvelteFlow /> component, you will have to wrap the hook call in a $derived.

Old API

// Sidebar.svelte
 
const { addNode, deleteNodes, fitView } = useSvelteFlow();

New API

// Sidebar.svelte
 
let { addNode, deleteNodes, fitView } = $derived(useSvelteFlow());

Binding the viewport

Old API

const viewport = writable<Viewport>({ x: 100, y: 100, zoom: 1.25 });
 
<SvelteFlow {viewport} />

New API

let viewport = $state < Viewport > { x: 100, y: 100, zoom: 1.25 };
 
<SvelteFlow bind:viewport />;

Custom Connection Line

Using a custom Connection Line was possible before by passing it to a slot. In Svelte Flow 1.0 we introduced a connectionLineComponent prop for this:

Old API

<SvelteFlow {nodes} {edges}>
  <ConnectionLine slot="connectionLine" />
  <Background variant={BackgroundVariant.Lines} />
</SvelteFlow>

New API

<SvelteFlow {nodes} {edges} connectionLineComponent={ConnectionLine}>
  <Background variant={BackgroundVariant.Lines} />
</SvelteFlow>

New Features

colorModeSSR

You can pass a fallback color mode for server side rendering when colorMode is set to 'system'.