# Svelte Flow Documentation
What is Svelte Flow?
Svelte Flow is a library that allows you to create interactive, node-based user
interfaces: flowcharts, diagrams, visual programming tools, and workflows inside
your svelte applications. It supports theming, custom nodes and edges, a library
of shadcn UI components, and offers a large collection of examples for rapid development.
Developers can leverage the Svelte Flow Pro platform for advanced features like
real-time collaboration, complex layouts, and enhanced performance, making it
suitable for both simple and large-scale, production-ready visual applications.
## Learn
### Quick Start
This page will take you from zero to a working Svelte Flow app in a few minutes. From
there, you can take a deeper look at what Svelte Flow is all about, check out the
examples, or dive into the API docs. If you want to get up and running as soon as
possible, you're in the right place!
#### Installation
To install Svelte Flow in your existing Svelte project, run the following command:
```bash copy npm2yarn
npm install @xyflow/svelte
```
#### Templates
If you want to get started right away, you can use a template.
##### Svelte Flow Vite template
We have a ready-to-use
[Vite template](https://github.com/xyflow/vite-svelte-flow-template) that you can use to
get up and running in no time.
```bash copy npm2yarn
npx degit xyflow/vite-svelte-flow-template app-name
```
##### SvelteKit template
Alternatively, you can spin up a new [Svelte](https://svelte.dev/) project with
[SvelteKit](https://svelte.dev/docs/kit/introduction) and [Vite](https://vite.dev/)
templates.
```bash copy npm2yarn
npx sv create my-svelte-flow-app
```
Next, `cd` into your project directory and install the Svelte Flow package:
```bash copy npm2yarn
npm install @xyflow/svelte
```
#### Usage
The `@xyflow/svelte` package exports the `` component, which is the
entrypoint for your flow. Importing the default styles and defining a handful of nodes and
edges are all we need to get started!
There are a few things to pay attention to here:
* You must import the Svelte Flow stylesheet.
* `` inherits the size of its parent. Wrap it in an element with dimensions.
* Use [`$state.raw`](https://svelte.dev/docs/svelte/$state#$state.raw) instead of deeply reactive state for
the `nodes` and `edges` for [performance reasons](https://github.com/sveltejs/svelte/issues/11851).
```svelte
```
#### Result
Et voila. You've already created your first interactive flow!
Example: learn/quickstart
##### index.ts
```ts
import { mount } from 'svelte';
import App from './App.svelte';
import './index.css';
mount(App, {
target: document.getElementById('app')!,
});
```
##### index.html
```html
Svelte Flow Example
```
##### index.css
```css
html,
body {
margin: 0;
font-family: sans-serif;
}
#app {
width: 100vw;
height: 100vh;
}
```
##### App.svelte
```svelte
```
#### Next steps
### Server Side Rendering
### Server side rendering, server side generation
This is an advanced use case and assumes you are already familiar with Svelte Flow. If you're new to Svelte Flow, check out our [getting started guide](/learn).
In this guide, you'll learn how to configure Svelte Flow for server-side rendering, enabling you to:
* Generate static HTML diagrams for documentation
* Render Svelte Flow diagrams in non-JavaScript environments
* Create dynamic Open Graph images for social media sharing
(For client-side image generation, check out our [download image example](/examples/misc/download-image).)
##### Why Server-Side Rendering is Complex
To understand why server-side rendering in Svelte Flow requires special configuration, let's look at what Svelte Flow typically handles on the client side:
1. **Node Dimension Calculation**
* Nodes can contain any content, so their dimensions are determined by the browser's layout engine
* This dynamic sizing isn't available during server-side rendering
2. **Handle Position Detection**
* Edge connections require precise handle positions
* These positions are calculated based on CSS layout, which isn't available on the server
3. **Container Size Adaptation**
* Svelte Flow adapts to its container's dimensions
* Server-side rendering needs explicit dimensions
##### Node Dimensions
The most crucial aspect of server-side rendering is specifying node dimensions. On the client, Svelte Flow automatically measures nodes and stores dimensions in `measured.width` and `measured.height`. For server-side rendering, you must provide these dimensions explicitly using either:
Node Dimension Options:
1. `width` and `height`: Static dimensions that won't change
2. `initialWidth` and `initialHeight`: Dynamic dimensions that may change after client-side hydration
```svelte
```
##### Handle Positions
To render edges on the server, you need to provide handle positions explicitly. On the client, Svelte Flow calculates these positions automatically, but for server-side rendering, you must specify them using the `handles` property:
```svelte
```
##### Using `fitView` with Server-Side Rendering
If you know your container's dimensions, you can use `fitView` during server-side rendering by providing the container's width and height:
```svelte
```
##### Generating Static HTML
To create static HTML output, you can use Svelte's server-side rendering capabilities. This generates an HTML string that you can use for static files or HTTP responses:
```svelte filename="Flow.svelte"
```
```js
import { render } from 'svelte/server';
import Flow from './Flow.svelte';
function toHTML({ nodes, edges, width, height }) {
const { body } = render(Flow, {
props: { nodes, edges, width, height },
});
return body;
}
```
### Usage with TypeScript
Svelte Flow is written in TypeScript because we value the additional safety barrier it provides.
We export all the types you need for correctly typing data structures and functions you pass to the Svelte Flow component. We also provide a way to extend the types of nodes and edges.
#### Basic Usage
Let's start with the essential types needed for a basic implementation. While TypeScript can infer some types automatically, we'll define them explicitly for clarity.
```svelte
```
##### Custom Nodes
When working with [custom nodes](/learn/customization/custom-nodes), you can extend the base `Node` type to include your custom data. There are two main approaches:
1. For **multiple custom nodes**, specify a custom `Node` type as a generic to `NodeProps`:
```svelte
A special number: {data.number}
```
โ ๏ธ When defining node data separately, you must use `type` (interfaces won't work):
```ts
type NumberNodeData = { number: number };
type NumberNodeType = Node;
```
2. For **a single custom node** that renders different content based on the node type, use a union type:
```svelte
{#if type === 'number'}
A special number: {data.number}
{:else}
A special text: {data.text}
{/if}
```
##### Custom Edges
Similar to custom nodes, you can extend the base `Edge` type for [custom edges](/learn/customization/custom-edges):
```svelte
```
#### Advanced Usage
In complex applications, you'll likely have multiple custom nodes and edges with different data structures. When using built-in functions and hooks, you'll need to properly [narrow down](https://www.typescriptlang.org/docs/handbook/2/narrowing.html) the types to prevent runtime errors.
##### `Node` and `Edge` Type Unions
Many functions, callbacks, and hooks (including the SvelteFlow component) expect `NodeType` or `EdgeType` generics. These are unions of all your custom node and edge types. As long as you've properly typed your data objects, you can use their exported types.
If you're using any built-in nodes ('input', 'output', 'default') or edges ('straight', 'step', 'smoothstep', 'bezier'), include
the `BuiltInNode` and `BuiltInEdge` types from `@xyflow/svelte` in your union type.
```svelte
```
##### Hooks
You can use these type unions to properly type the return values of hooks:
```svelte
```
##### Type Guards
TypeScript provides several ways to implement [type guards](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#typeof-type-guards). One common approach is to create type guard functions like `isNumberNode` or `isTextNode` to filter specific nodes from a list:
```ts
function isNumberNode(node: NodeType): node is NumberNodeType {
return node.type === 'number';
}
// numberNodes is now correctly typed as NumberNodeType[]
let numberNodes = $derived(nodes.filter(isNumberNode));
```
### Building a Flow
In the following pages we will introduce you to the core concepts of Svelte Flow and
explain how to create a basic interactive flow. A flow consists of
[nodes](/api-reference/types/node), [edges](/api-reference/types/edge) and the viewport.
If you haven't reviewed our [Key Concepts](/learn/concepts/terms-and-definitions) yet,
we recommend doing that first.
To follow along with this guide you will need to have a Svelte project set up and install
the `@xyflow/svelte` package:
```bash copy npm2yarn
npm install @xyflow/svelte
```
#### Creating the flow
Let's start by creating an empty flow with viewport
[``](/api-reference/components/controls) and a dotted
[``](/api-reference/components/background).
### Add imports
First, import the Svelte Flow Component and its required styles into your
project. We'll also import the `Background` component for visual enhancement,
and the `Controls` component for the viewport controls.
```svelte
```
##### Render SvelteFlow
Next, render the main component inside an element with defined dimensions and place the
[``](/api-reference/components/background) and [``](/api-reference/components/controls) components inside `SvelteFlow`.
Content inside `SvelteFlow` stays fixed on top of the viewport. The `Background`
component transforms its pattern to match viewport movement.
```svelte
```
##### Empty flow
That's it! You have created your first empty flow ๐
If everything is set up correctly, you should see a blank canvas like this:
Example: learn/building-a-flow-1
##### index.ts
```ts
import { mount } from 'svelte';
import App from './App.svelte';
import './index.css';
mount(App, {
target: document.getElementById('app')!,
});
```
##### index.html
```html
Svelte Flow Example
```
##### index.css
```css
html,
body {
margin: 0;
font-family: sans-serif;
}
```
##### App.svelte
```svelte
```
#### Adding nodes
Now that the flow is set up, let's add some nodes - each node represents an element in
your diagram with a specific position and content.
### Create node objects
In the `