Skip to main content
FlowDrop is built with Svelte 5, but can be mounted into any framework via the mount API.

Svelte (Native)

Use FlowDrop components directly in Svelte:
<script>
  import { App } from '@flowdrop/flowdrop/editor';
  import { createEndpointConfig } from '@flowdrop/flowdrop/core';
  import '@flowdrop/flowdrop/styles';

  const endpointConfig = createEndpointConfig('/api/flowdrop');
</script>

<App
  {endpointConfig}
  showNavbar={true}
  onAfterSave={async (workflow) => console.log('Saved:', workflow.id)}
/>
For SvelteKit, ensure FlowDrop runs only on the client:
<script>
  import { browser } from '$app/environment';
  import { App } from '@flowdrop/flowdrop/editor';
</script>

{#if browser}
  <App {endpointConfig} />
{/if}

Vanilla JS / React / Vue / Angular

Use the mount API to embed FlowDrop in any container element:
import { mountFlowDropApp } from '@flowdrop/flowdrop/editor';
import { createEndpointConfig } from '@flowdrop/flowdrop/core';
import '@flowdrop/flowdrop/styles';

const app = await mountFlowDropApp(document.getElementById('editor'), {
  endpointConfig: createEndpointConfig('/api/flowdrop'),
  eventHandlers: {
    onDirtyStateChange: (isDirty) => console.log('Unsaved:', isDirty),
    onAfterSave: async (workflow) => console.log('Saved!', workflow)
  }
});

// Programmatic control
app.save();
app.getWorkflow();
app.isDirty();
app.destroy();
The returned handle also exposes app.export() and the mount’s state container at app.instance. For programmatic state changes, reach through the instance — app.instance.workflow.actions.*, app.instance.history.undo(), and so on. See Mount API for the complete options and return value.

API Configuration

Connect to your backend by configuring endpoints:
import { createEndpointConfig } from '@flowdrop/flowdrop/core';

// Simple: just a base URL (all endpoints use defaults)
const config = createEndpointConfig('/api/flowdrop');

// Custom: override specific endpoint paths
const config = createEndpointConfig({
  baseUrl: 'https://api.example.com',
  endpoints: {
    nodes: { list: '/nodes', get: '/nodes/{id}' },
    workflows: {
      list: '/workflows',
      get: '/workflows/{id}',
      create: '/workflows',
      update: '/workflows/{id}'
    }
  }
});
See Backend Implementation for which endpoints to implement.

Authentication

FlowDrop supports three auth providers. Quick examples:
import { NoAuthProvider, StaticAuthProvider, CallbackAuthProvider } from '@flowdrop/flowdrop/core';

// No auth (development)
authProvider: new NoAuthProvider();

// Static bearer token
authProvider: new StaticAuthProvider({ type: 'bearer', token: 'your-jwt' });

// Dynamic token with refresh (enterprise)
authProvider: new CallbackAuthProvider({
  getToken: async () => authService.getAccessToken(),
  onUnauthorized: async () => authService.refreshToken()
});
For full details on each provider, token refresh patterns, and OAuth2 integration, see Authentication Patterns.

Event Handlers

React to all 11 editor lifecycle events:
const app = await mountFlowDropApp(container, {
  eventHandlers: {
    onWorkflowChange: (workflow, changeType) => {
      analytics.track('workflow_modified', { changeType });
    },
    onDirtyStateChange: (isDirty) => {
      saveButton.disabled = !isDirty;
    },
    onBeforeSave: async (workflow) => {
      // Return false to cancel save
    },
    onAfterSave: async (workflow) => {
      showNotification('Saved!');
    },
    onApiError: (error, operation) => {
      if (error.message.includes('401')) {
        redirectToLogin();
        return true; // suppress default toast
      }
    }
  }
});
The mount options bag groups handlers under eventHandlers. The <App> component instead takes the same handlers as flat on* props (onAfterSave, onApiError, …). For the complete event reference, see Event System.

Feature Flags

Enable optional editor features:
const app = await mountFlowDropApp(container, {
  features: {
    autoSaveDraft: true, // default: true
    autoSaveDraftInterval: 30000, // default: 30 seconds
    showToasts: true // default: true
  }
});

Read-Only & Lock Modes

The mode option controls canvas editing. 'readonly' and 'locked' both disable node dragging, connecting, selecting, proximity-connect, and node swap.
// Read-only: no canvas editing
const app = await mountFlowDropApp(container, {
  mode: 'readonly'
});

// Locked: same disabled interactions, distinct intent
const app = await mountFlowDropApp(container, {
  mode: 'locked'
});

Next Steps