> ## Documentation Index
> Fetch the complete documentation index at: https://flowdrop.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Architecture overview

> How FlowDrop's modules, components, stores, and services fit together.

export const AsciiDiagram = ({children}) => {
  return <div className="ascii-diagram">{children}</div>;
};

This page explains how FlowDrop is structured internally, so you can make
informed decisions about what to import, how to integrate, and where to extend.

## High-level architecture

FlowDrop is a **frontend library** that communicates with **your backend** via REST.

<AsciiDiagram>
  ```
  ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐                                         
             Browser                                                    
  │                           │                                         
     ┌─────────────────────┐                                            
  │  │      FlowDrop       │  │                                         
     ├─────────────────────┤             ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐
  │  │User Interface       │  │                   Your Backend          
     │ │                   │             │                             │
  │  │ ├─╼ Navbar          │  │             ┌────────────────────────┐  
     │ ├─╼ Canvas          │             │  │   Python/PHP/NodeJS    │ │
  │  │ ╰─╼ Config Panel    │  │             │       Framework        │  
     │                     │             │  ├────────────────────────┤ │
  │  ├─────────────────────┤  │             │Storage and Business    │  
     │Browser Storage      │      REST   │  │Logic                   │ │
  │  │ │                   │  │───API───▶   │ │                      │  
     │ ├─╼ Workflow        │             │  │ ├─╼ Nodes              │ │
  │  │ ├─╼ History         │  │             │ ├─╼ Workflows          │  
     │ ╰─╼ Settings        │             │  │ ├─╼ Access             │ │
  │  │                     │  │             │ ├─╼ Persistant Storage │  
     ├─────────────────────┤             │  │ ╰─╼ Execution          │ │
  │  │Services             │  │             │                        │  
     │ │                   │             │  │                        │ │
  │  │ ├─╼ API Client      │  │             └────────────────────────┘  
     │ ├─╼ Drafts          │             └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘
  │  │ ╰─╼ Toasts          │  │                                         
     │                     │                                            
  │  └─────────────────────┘  │                                         
   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ 

  ```
</AsciiDiagram>

## Module structure

FlowDrop is tree-shakable. Each sub-module has different dependencies and bundle cost:

| Module                             | What it provides                                 | Heavy deps           |
| ---------------------------------- | ------------------------------------------------ | -------------------- |
| `@flowdrop/flowdrop/core`          | Types, utilities, auth providers, config helpers | None                 |
| `@flowdrop/flowdrop/editor`        | WorkflowEditor, mount functions, node components | @xyflow/svelte       |
| `@flowdrop/flowdrop/form`          | SchemaForm, field components                     | None                 |
| `@flowdrop/flowdrop/form/code`     | Code & template editors                          | CodeMirror (\~300KB) |
| `@flowdrop/flowdrop/form/markdown` | Markdown editor                                  | CodeMirror           |
| `@flowdrop/flowdrop/display`       | MarkdownDisplay                                  | marked               |
| `@flowdrop/flowdrop/playground`    | Playground, chat, interrupts                     | Editor + Form        |
| `@flowdrop/flowdrop/settings`      | Settings panel, theme toggle                     | Form                 |
| `@flowdrop/flowdrop/styles`        | CSS design tokens                                | None                 |
| `@flowdrop/flowdrop`               | Bootstrap front door (App, mount, instances)     | Bootstrap surface    |

## Component hierarchy

When you mount `mountFlowDropApp()`, this is the component tree:

```text theme={null}
App
├── Navbar
│   ├── Logo
│   ├── WorkflowName (editable)
│   ├── Save / Export buttons
│   ├── Custom NavbarActions
│   └── ThemeToggle / Settings
├── NodeSidebar
│   ├── Search
│   └── CategoryGroups
│       └── NodeCards (draggable)
├── WorkflowEditor (@xyflow/svelte canvas)
│   ├── Nodes (WorkflowNode, SimpleNode, GatewayNode, etc.)
│   │   └── Ports (input/output handles)
│   ├── Edges (styled by category)
│   └── ConnectionLine
├── ConfigPanel (right side, on node click)
│   ├── NodeHeader (name, type, icon)
│   └── SchemaForm (generated from configSchema)
│       └── FormFields (text, select, code, template, etc.)
└── ToastContainer
```

`mountWorkflowEditor()` mounts just the canvas — no navbar, no sidebar.

Each mount produces one such tree backed by its own instance; node/field
registries and settings are shared across all trees on the page.

## Stores

FlowDrop uses **Svelte 5 runes** for state management. Each mount creates a
per-instance `FlowDropInstance` container that holds these stores:

| Store                   | Purpose                | Key state                                   |
| ----------------------- | ---------------------- | ------------------------------------------- |
| **workflowStore**       | Central workflow state | nodes, edges, metadata, isDirty             |
| **historyStore**        | Undo/redo              | past states, future states, canUndo/canRedo |
| **settingsStore**       | User preferences       | theme, editor behavior, UI config           |
| **playgroundStore**     | Playground sessions    | sessions, messages, isExecuting             |
| **interruptStore**      | Human-in-the-loop      | pending/resolved interrupts                 |
| **categoriesStore**     | Node categories        | category definitions, colors                |
| **portCoordinateStore** | Handle positions       | port coordinates for edge rendering         |

### Instance model

Every mount creates an isolated `FlowDropInstance` container holding the stores
above (workflow, history, playground, interrupts, categories, port coordinates,
and pipeline-panel state), resolved through Svelte context. Multiple editors can
therefore coexist on one page without sharing state.

See the [multiple instances guide](/guides/multiple-instances) for details.

## Services

Services handle communication and side effects:

| Service                | Purpose                                                     |
| ---------------------- | ----------------------------------------------------------- |
| **API client**         | HTTP requests to your backend (nodes, workflows, execution) |
| **Draft storage**      | Auto-save to localStorage                                   |
| **Toast service**      | Success/error/loading notifications                         |
| **Dynamic schema**     | Fetch config schemas from API at runtime                    |
| **Playground service** | Manage sessions, poll for messages                          |
| **Interrupt service**  | Submit interrupt resolutions                                |
| **History service**    | Track and replay state changes                              |
| **Settings service**   | Load/save preferences (localStorage + API)                  |

## Data flow

Here's what happens when a user makes a change:

<AsciiDiagram>
  ```
  ┌───────────────────────┐                         
  │      User action      │                         
  │     (drag node, edit  │                         
  │  config, draw edge)   │                         
  └───────────────────────┘                         
              │                                     
              ▼                                     
  ┌───────────────────────┐                         
  │Component event handler│                         
  └───────────────────────┘                         
              │                                     
              │                                     
              ▼                                     
  ┌───────────────────────┐                         
  │ workflowStore update  │                         
  │   (state mutation)    │                         
  └───────────────────────┘                         
              │                                     
              │       ┌────────────────────────────┐
              │       │        historyStore        │
              ├──────▶│      records snapshot      │
              │       │         (for undo)         │
              │       └────────────────────────────┘
              │       ┌────────────────────────────┐
              │       │          isDirty           │
              ├──────▶│      flag set to true      │
              │       │                            │
              │       └────────────────────────────┘
              │       ┌────────────────────────────┐
              │       │                            │
              ├──────▶│       UI re-renders        │
              │       │                            │
              │       └────────────────────────────┘
              │       ┌────────────────────────────┐
              │       │                            │
              │       │ onWorkflowChange(workflow, │
              │       │        changeType)         │
              │       │                            │
              ├──────▶│                            │
              │       │ your callback — analytics, │
              │       │      validation, etc.      │
              │       │                            │
              │       └────────────────────────────┘
              │       ┌────────────────────────────┐
              │       │  onDirtyStateChange(true)  │
              │       │                            │
              └──────▶│your callback — update save │
                      │        button, etc.        │
                      │                            │
                      └────────────────────────────┘
  ```
</AsciiDiagram>

When the user saves:

<AsciiDiagram>
  ```
                  ┌─────────────────────┐                             
                  │  User clicks Save   │                             
                  └─────────────────────┘                             
                             │                                        
                             ▼                                        
               ┌───────────────────────────┐                          
               │  onBeforeSave(workflow)   │                          
               └───────────────────────────┘                          
                             │                                        
                             │                                        
               ┌──False──────┴──────────────┐                         
               │                            │                         
               ▼                            ▼                         
    ┌─────────────────────┐      ┌─────────────────────┐              
    │                     │      │     API client:     │              
    │       Cancel        │      │                     │              
    │                     │      │ PUT /workflows/{id} │              
    └─────────────────────┘      └─────────────────────┘              
                                            │                         
                                            │                         
                                            │                         
                  ┌─────Success─────────────┴───Error─┐               
                  │                                   │               
                  │                                   │               
                  ▼                                   ▼               
  ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
  ┃isDirty = false, draft cleared┃    ┃      Toast notification      ┃
  ┃                              ┃    ┃                              ┃
  ┣──────────────────────────────┫    ┣──────────────────────────────┫
  │    onAfterSave(workflow)     │    │ onSaveError(error, workflow) │
  └──────────────────────────────┘    ├──────────────────────────────┤
                                      │  onApiError(error, 'save')   │
                                      └──────────────────────────────┘
  ```
</AsciiDiagram>

## Registry system

FlowDrop has two registries for extending the editor:

### Node component registry

Register custom Svelte components for new node types against the instance's
`fd.nodes` registry:

```typescript theme={null}
import { getInstance } from '@flowdrop/flowdrop/editor';
const fd = getInstance();
fd.nodes.registerCustom('my-custom-node', 'My Custom Node', MyNodeComponent);
```

### Field component registry

Register custom form fields for config schemas against `fd.fields`:

```typescript theme={null}
import { getInstance } from '@flowdrop/flowdrop/editor';
const fd = getInstance();
fd.fields.register('my-field', {
  component: MyFieldComponent,
  matcher: (schema) => schema.format === 'my-field',
  priority: 10
});
```

Both registries are **instance-scoped** — seeded with builtins in the instance
constructor and resolved via `getInstance()`. You can register after mounting.

<Accordion title="Why registration works after mount">
  `BaseRegistry` tracks a version counter that invalidates dependent `$derived`
  reads, so registrations made after mount still take effect.
</Accordion>

## Next steps

* [What is a Workflow?](/concepts/what-is-a-workflow) — the mental model
* [Quick Start](/docs/quickstart) — mount FlowDrop in your app
* [Backend Implementation](/guides/integration/backend-implementation) — build the API FlowDrop expects
* [Event System](/guides/advanced/event-system) — hook into every lifecycle event
