Quick Start
This page will take you from zero to a working ShipTemplates Workflow in a few minutes — both inside your Dashboard Visual Studio ↗ and embedded inside your React SaaS. If you just want to have a look around and get an impression of the engine, check out our interactive Live Playground ↓.
Installation
To install ShipTemplates Workflow in your existing React / Next.js project, run the following command:
Play online
You can try ShipTemplates Workflow without setting anything up locally by launching our live workspace studio or inspecting the OpenAPI 3.1 Sandbox ↗:
How to Use Workflows on the Dashboard
Inside your workspace dashboard (/dashboard/workflows), every workflow goes through four deterministic stages:
Choose from the 3 starter blueprints in /dashboard/workflows or start a blank DAG. Each save creates an immutable revision.
Store Slack, OpenAI, or Postgres credentials in /dashboard/credentials. Keys are decrypted only inside the isolated worker at step execution time.
Connect ports on the visual canvas and inject upstream JSON via {{ $json.body.amount }}. Kahn's algorithm validates the DAG is cycle-free.
Trigger via Manual Run, Cron Schedule, or Signed Webhook and inspect per-node inputs, outputs, and retries in /dashboard/executions.
Templates
If you want to get started right away, you can use a template:
ShipTemplates Workflow Next.js template
We have a ready-to-use Next.js + BullMQ template ↗ that you can use to get up and running in no time:
Vite / Next.js template with React
To create a new embedded workflow project from scratch, first spin up a new React project — we recommend using Next.js ↗ or Vite:
Next, cd into your new project folder and add @shiptemplates/workflow-embed as a dependency:
Lastly, spin up the dev server and you're good to go!
Usage
We will render the <WorkflowBuilder /> component from the @shiptemplates/workflow-embed package. This, and defining a handful of node objects, edge objects and event handlers, is all we need to get something going! Clear out everything inside App.tsx and add the following:
If you are using Tailwind CSS 4, you need to make sure the canvas stylesheet @xyflow/react/dist/style.css is imported after your base global.css stylesheet, and always pass a short-lived server-minted emb_v1.* token (never a raw stk_live_* key). Read more.
import { useState, useCallback } from 'react';
import {
WorkflowBuilder,
applyNodeChanges,
applyEdgeChanges,
addEdge,
} from '@shiptemplates/workflow-embed';
import '@xyflow/react/dist/style.css';
const initialNodes = [
{ id: 'n1', type: 'trigger.webhook', position: { x: 0, y: 0 }, data: { label: 'Node 1' } },
{ id: 'n2', type: 'action.slack', position: { x: 0, y: 100 }, data: { label: 'Node 2' } },
];
const initialEdges = [{ id: 'n1-n2', source: 'n1', target: 'n2', animated: true }];
export default function App({ embedToken, workflowId }: { embedToken: string; workflowId: string }) {
const [nodes, setNodes] = useState(initialNodes);
const [edges, setEdges] = useState(initialEdges);
const onNodesChange = useCallback(
(changes) => setNodes((nodesSnapshot) => applyNodeChanges(changes, nodesSnapshot)),
[],
);
const onEdgesChange = useCallback(
(changes) => setEdges((edgesSnapshot) => applyEdgeChanges(changes, edgesSnapshot)),
[],
);
const onConnect = useCallback(
(params) => setEdges((edgesSnapshot) => addEdge(params, edgesSnapshot)),
[],
);
return (
<div style={{ width: '100%', height: '640px' }}>
<WorkflowBuilder
workflowId={workflowId}
embedToken={embedToken}
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onConnect={onConnect}
fitView
/>
</div>
);
}There are two things to pay attention to here:
- 🎨You must import the
@xyflow/react/dist/style.cssstylesheet and provide a server-mintedemb_v1.*embed token for the builder to work. - 📐The
<WorkflowBuilder />component must have a parent element with an explicit width and height.
Result
Et voilà! You've already created your first interactive flow! 🎉
Built-In 11 Node Components
All 11 node types ship pre-registered in the dashboard studio and @shiptemplates/workflow-core:
trigger.manualTriggerManual Studio Trigger
Run workflows on-demand from the dashboard canvas or REST API with custom JSON test payloads.
trigger.webhookTriggerHMAC-SHA256 Signed Webhook
Verifies X-Workflow-Signature with constant-time crypto.timingSafeEqual before enqueueing runs.
trigger.scheduleTriggerCron Schedule Trigger
Timezone-aware recurring BullMQ cron schedules (e.g. 0 9 * * 1-5) with idempotency keys.
logic.if_elseLogicIF / ELSE Conditional Branch
Evaluates sandboxed expressions (==, !=, >, >=, contains) and routes down true or false handles.
logic.switchLogicMulti-Route Switch
Routes incoming payloads across up to 8 named case handles plus a default fallback port.
logic.delayLogicDurable BullMQ Delay
Persists execution state in PostgreSQL and resumes via BullMQ delayed timers without blocking.
logic.loopLogicBatch Array Iterator
Splits arrays into configurable batch chunks and aggregates downstream execution outputs.
action.httpActionSSRF-Guarded HTTP Client
Blocks RFC1918 private networks, loopback, and cloud metadata IPs (169.254.169.254) automatically.
action.ai_llmActionAI LLM Structured Completion
Executes OpenAI / Anthropic prompts with JSON schema validation and encrypted vault API keys.
action.slackActionSlack Channel Dispatcher
Sends formatted Block Kit notifications using decrypted credentials from the tenant vault.
action.postgresActionParameterized SQL Query
Runs read/write parameterized SQL queries ($1, $2) against external tenant databases safely.
Use double-curly expressions inside any action or branch node parameter on the dashboard: