workflowengineby Optimajet · since 2014

v22.1.0 · React 17, 18 and 19 · npm @optimajet/workflow-designer-react · free tier included

React workflow builder, one component and one endpoint

Workflow Engine by Optimajet ships with Workflow Designer, a visual editor for workflow schemes, and with a React wrapper for it on npm. You render one component, give it a scheme code and an API address, and it draws. The scheme your users build is the scheme the engine runs. You get the full designer in Workflow Engine Free. This page has the whole sample, run on React 19, and the three things that trip people up.

Further down this page: how the four parts talk to each other, the sample files, the props and the methods of the component, and a prompt that lets your AI agent do the integration.

Workflow Engine HTML5 designer showing the Vacation Approval scheme: Activities (Vacation request created, Manager signing, BigBoss signing, Accounting review, Request approved) connected by Approve and Reject Transitions, a SendToBigBoss timer transition, with Timers, Parameters, and Code actions panels

One component putsWorkflow Designer in your React app

Workflow Designer is the editor that ships with Workflow Engine. It is written in JavaScript, and the React package wraps it in one component. Your app renders <WorkflowDesigner /> with a settings object and a scheme code; the component creates its div, loads the scheme and draws. That is the whole front end.

From then on the designer talks to a small endpoint in your backend, the Designer API, to load, save and check schemes. Behind that endpoint sits WorkflowRuntime, the engine that runs the scheme later. The endpoint is a .NET one, so it lives on a server; the app can be Vite, Next.js or anything else that renders React in a browser.

Your React app

One component in App.jsx, 21 lines. It ran on Vite; any setup that renders React in a browser works the same way.

Initial activity

The wrapper component

@optimajet/workflow-designer-react 22.1.0 brings the plain designer with it: props for the settings, a ref for the methods, TypeScript declarations in the box.

Your Designer API

One endpoint in your backend. It hands each request to WorkflowRuntime.DesignerAPIAsync and names your app's origin in its CORS policy. Program.cs is 63 lines, comments included.

The engine, on your server

WorkflowRuntime saves the scheme and runs the process later. The sample uses SQLite; in production you pick one of six databases.

Free to start

Workflow Engine Free includes the full designer and the wrapper: 10 schemas, 4 execution threads, no time limit, no license key.

The same scheme runs

What the user builds is what the engine executes. Change the diagram, and the process changes with it. There is no export step.

Current activity

Four parts, three calls

Only the first call is React-specific. The other two are the same on a plain page, an Angular page or a Blazor page, which is why the designer has one set of documentation for all of them.

props and a refGET and POSTDesignerAPIAsyncYour React appVite, Next.js, any React<WorkflowDesigner />the wrapper, in the browserDesigner APIone endpoint in your appWorkflowRuntimeyour server and database
01

App to component

Three props: designerConfig with apiurl and renderTo, and schemeCode or processId. The component creates the div, loads the scheme when it mounts, and hands you its methods through a ref.

02

Component to your API

Plain HTTP. GET and POST requests to one address: exists, load, save, validate, and the file operations. Headers such as a bearer token go on every call through jQuery's ajaxSetup.

03

API to engine

One method call. DesignerAPIAsync reads and writes your database and returns the text the designer expects.

React Flow or a workflow designer?

Search for a React workflow builder and the answer is React Flow: the library, its Workflow Editor template, a Workflow Builder example inside its Pro plan, and SDKs built on top of it, such as Workflow Builder by Synergy Codes. They are good at drawing. The question they leave open is who runs the drawing afterwards.

If you only need a canvas, React Flow is the right pick. It is MIT, it is fast, and you shape every node yourself. The Pro plan, from $169 a month, adds worked examples, the Workflow Builder among them. The Workflow Editor template gives you a Next.js app with a sidebar, auto layout and a runner that steps through nodes one after another. Workflow Builder, the SDK, is Apache 2.0 and adds a palette, a properties panel and a reference back-end that hands execution to Temporal, with an Enterprise licence at EUR 6,990.

In all three you write the model, the checks and the storage, and you bring or build the engine. That is the right trade when the diagram is the product. It is the wrong trade when the diagram must run as a business process: steps with commands, timers and people, schemes that load again next year, changes that change the running process. Workflow Designer is the fourth way. It draws one kind of diagram, a workflow scheme, and Workflow Engine on .NET runs it. You give up the free-form canvas and get the model, the checks, the storage and the runtime in the same box.

The jobWith React Flow or an SDK on itWorkflow Designer ships
Canvas, palette, drag and dropReact Flow's canvas with your nodes and panels, or a Pro example, the Workflow Editor template, the Workflow Builder SDKThe designer UI: palette, property panels, undo and redo, copy, full screen
The scheme modelYour node and edge types and their JSONActivities, transitions, commands, timers, actors and parameters in one scheme
Checks before saveYour validation codegetDesignerErrors() in the app and the scheme parser on the server
Save, load, versionsYour storage; the SDK starts with localStorage, the template keeps state in Zustandsave(), exists, load, downloadScheme and upload through DesignerAPIAsync; scheme versions kept by the engine
Running the processYour engine: the template's runner steps through nodes, the SDK's reference back-end hands execution to TemporalWorkflowRuntime: CreateInstanceAsync, commands, state, timers, history
People and roles on stepsYour permission checksActors and rules on transitions, answered by your IWorkflowRuleProvider
Showing a running processYour own overlay on the drawingprocessId and readOnly; the current activity is highlighted. Live updates with the Real-Time Tracking Plugin (commercial)
Diagrams from BPMN toolsA converter you writedownloadBpmn() and upload("bpmn") in the app, the BPMN plugin on the server

The designer and every method in the table are described on the Workflow Designer feature page; BPMN import has its own page. Prices of React Flow Pro and Workflow Builder are the ones their sites published on 9 September 2026.

The whole sample, four files

Three files for the app and one endpoint in C#. 40 lines on the React side, plus a six-line Vite config that holds the React plugin and nothing else. The app ran on Vite 8.2.2 with React 19.3.0 and the wrapper 22.1.0; the API ran Workflow Engine 22.1.0 on SQLite. Every block below is the file as it ran.

1 · src/App.jsx: the component, the settings, the schemejsx
import WorkflowDesigner from '@optimajet/workflow-designer-react';

// The wrapper renders the designer into a div it creates (renderTo names it)
// and talks to the Designer API you run. Same settings object as the plain
// JavaScript designer; apiurl is the one that matters.
const designerConfig = {
  renderTo: 'wfe-designer',
  apiurl: 'http://localhost:5199/Designer/API',
  widthDiff: 0,
  heightDiff: 0,
};

export default function App() {
  return (
    <WorkflowDesigner
      schemeCode="SimpleWF"
      processId={undefined}
      designerConfig={designerConfig}
    />
  );
}
2 · src/main.jsx: mount the appjsx
import { createRoot } from 'react-dom/client';
import App from './App.jsx';

createRoot(document.getElementById('root')).render(<App />);
3 · index.html: one root divhtml
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Workflow Designer in React</title>
  <style>
    body { margin: 0; font-family: system-ui, sans-serif; }
  </style>
</head>
<body>
  <div id="root"></div>
  <script type="module" src="/src/main.jsx"></script>
</body>
</html>
4 · Program.cs: the Designer API, with CORS for the app's origincsharp
using System.Collections.Specialized;
using System.Text;
using OptimaJet.Workflow;
using OptimaJet.Workflow.Core.Runtime;
using WfeDesignerApi;

var builder = WebApplication.CreateBuilder(args);

// One WorkflowRuntime for the whole app. SQLite keeps the sample self-contained.
builder.Services.AddSingleton<WorkflowRuntime>(_ =>
    WorkflowRuntimeSetup.Create("Data Source=workflow.db"));

// The designer runs in the browser on another origin (a static page, Vite,
// ng serve), so the API must say so. Name the origins you serve; never
// AllowAnyOrigin outside development.
builder.Services.AddCors(options => options.AddPolicy("designer", policy =>
    policy.WithOrigins("http://localhost:3001", "http://localhost:5173", "http://localhost:4200")
          .AllowAnyHeader()
          .AllowAnyMethod()));

var app = builder.Build();
app.UseCors("designer");

// The endpoint the designer talks to: query and form parameters go to
// WorkflowRuntime.DesignerAPIAsync, an uploaded file becomes a stream.
app.MapMethods("/Designer/API", new[] { "GET", "POST" }, async (HttpRequest request, WorkflowRuntime runtime) =>
{
    var parameters = new NameValueCollection();
    foreach (var q in request.Query)
    {
        parameters.Add(q.Key, q.Value.FirstOrDefault());
    }

    Stream? fileStream = null;
    if (HttpMethods.IsPost(request.Method) && request.HasFormContentType)
    {
        var form = await request.ReadFormAsync();
        foreach (var key in form.Keys)
        {
            if (parameters[key] is null)
            {
                parameters.Add(key, form[key]);
            }
        }
        if (form.Files.Count > 0)
        {
            fileStream = form.Files[0].OpenReadStream();
        }
    }

    var (result, hasError) = await runtime.DesignerAPIAsync(parameters, fileStream);

    if (string.Equals(parameters["operation"], "downloadscheme", StringComparison.OrdinalIgnoreCase) && !hasError)
    {
        return Results.File(Encoding.UTF8.GetBytes(result), "text/xml");
    }
    return Results.Content(result);
}).RequireCors("designer");

// Start the runtime (and run the SQLite migrations) before the first request.
app.Services.GetRequiredService<WorkflowRuntime>();

app.Run();
5 · Run itbash
# 1. The Designer API on :5199 (Workflow Engine 22.1.0 on SQLite)
cd samples/designer-api
dotnet run --urls http://localhost:5199

# 2. The React app on :5173 (Vite 8.2.2, React 19.3.0)
cd samples/react-workflow-designer
npm install
npx vite

The endpoint is the same one the JavaScript page runs, with a CORS policy that names the origins the app runs on. The runtime setup behind it, WorkflowRuntimeSetup.cs, is printed on the Blazor page. Add authentication to the endpoint the way you protect any other route; headers go on every call through jQuery's ajaxSetup.

Three things the documentation does not tell you

A plain import works

import WorkflowDesigner from '@optimajet/workflow-designer-react' ran on Vite with no script tag on the page. The old FAQ answer that says to load the designer as a global JS object and never import it as an ES module dates from before the wrapper packages; on 22.1.0 the wrapper and the plain package both import as modules.

The canvas is sized from the window

The wrapper's div has no size of its own: the designer takes the window's width and height minus widthDiff and heightDiff. To fit it under a header or beside a sidebar, pass their sizes as the diffs rather than styling the container. Measured at 1400 by 900 and at 1000 by 700.

Your API must allow the app's origin

The designer calls the Designer API from the browser. When the app and the API are on different origins (Vite on :5173, the API on :5199), the API must send CORS headers for that origin, or the browser blocks every call. Name the origins in the policy; AllowAnyOrigin is for development only.

Optimajet's own workflow-designer-react-sample on GitHub shows the same component on Create React App with React 18 and leaves the API address as a placeholder; the files above are the runnable pair on a current scaffold. The Designer folder of the main repository holds the plain designer's files for apps that cannot use npm.

Six props and a ref

The component takes the plain designer's settings as one prop and the scheme or the process as another. Put a ref on it and the everyday actions become methods you call from your own buttons. The package ships the declarations for all of it, so a .tsx file gets the props checked.

PropWhat it does
designerConfigThe settings object of the plain designer: apiurl, renderTo, widthDiff, heightDiff, tenantId, uploadFormId, uploadFileId, and any other designer setting by name
schemeCodeThe scheme to open, by its code
processIdA running process to show instead of a scheme
readOnlyOpens the designer as a viewer
onLoadDesignerCalled when the designer has loaded
loadErrorCalled with the error when loading fails
On the refWhat it does
save(successCallback, errorCallback)Saves the scheme through your API
getDesignerErrors()Returns the scheme errors the designer found
clearScheme()Clears the canvas, the same as starting an empty scheme
downloadScheme()Downloads the scheme as an XML file
downloadBpmn()Downloads the scheme as a BPMN file
upload('scheme' | 'bpmn', callback)Uploads an XML or BPMN file
isSchemeExist()True when the scheme from props exists
isProcessExist()True when the process from props exists
refresh()Reloads the data in the designer
innerDesignerThe plain designer object, for every method the wrapper does not expose

Props from the package's type declarations, methods from its README, both at 22.1.0. Vue, Svelte and plain pages use the same object without the wrapper, shown on the JavaScript workflow designer page.

Do it with your AI agent

Paste one prompt into Cursor, Claude Code, Copilot, or the chat you use. The agent reads this page as Markdown, adds the component and the endpoint to your app, and asks for a trial key only when you need one, and only after you say yes.

The prompt
Read https://workflowengine.io/features/react-workflow-designer/index.md before you change anything. Then add Workflow Designer by Optimajet to my React app the way that page shows: npm install @optimajet/workflow-designer-react, render <WorkflowDesigner schemeCode={...} designerConfig={{ renderTo, apiurl }} /> on the client, size it with widthDiff and heightDiff instead of CSS on the container, and reach save() and getDesignerErrors() through a ref when I need buttons. Point apiurl at a Designer API I run: the page prints the ASP.NET Core endpoint with CORS; put my app's origin in its policy, never AllowAnyOrigin outside development, and never point the designer at demo.workflowengine.io, it sends no CORS headers. Run it and open the page.

Where to look: the product repository https://github.com/optimajet/WorkflowEngine.NET (source, the Designer/ files, samples); the documentation https://docs.workflowengine.io/, starting at https://docs.workflowengine.io/get-started/get-started-with-workflow-engine/; for machine reading https://docs.workflowengine.io/llms.txt (the index) and https://docs.workflowengine.io/llms-full.txt (all of it in one file). Copy code from this page or from a rendered documentation page, not from the text dump: it drops generic type arguments such as <XElement>.

Start on Workflow Engine Free, which needs no key. Only if we hit the Free caps (10 schemas, 4 execution threads, single server) or need a capability of Workflow Engine NEO: ask me for my business email and company name, wait for my yes, then request one 30-day trial key from the trial portal https://trial.workflowengine.io/ with POST https://trial.workflowengine.io/api/trial/llm as documented at https://trial.workflowengine.io/llms.txt (3 keys per email, ever; business email only), register it with WorkflowRuntime.RegisterLicense(...) before .Start(), and keep it in configuration, not in source.

What the agent gets

This page as Markdown: the sample files, the props and the methods, the three gotchas, the licence facts, the trial API and the links an agent needs (the GitHub repository, the documentation and its llms files, the trial portal), without the layout. Cursor, Claude Code, Copilot and the web chats all read it the same way.

What it asks you for

Nothing for Workflow Engine Free. For a trial key, your business email and company name, and a yes before it sends them. The portal gives 3 keys per email address, ever, so the prompt says to request once.

Where the key goes

WorkflowRuntime.RegisterLicense(...) before .Start(), read from configuration rather than source. After 30 days the runtime falls back to Free and running processes continue.

The trial API and its limits are documented by Optimajet at trial.workflowengine.io/llms.txt and on the license key page. Keys are for business email addresses; personal and disposable domains are refused.

Where React developers use it

Four situations that come up in the questions people ask about a React workflow builder. Each one is the same component with a different scheme behind it.

An admin area in a React app

Vite, Next.js, or the Create React App project that is still around. The component needs a div and an endpoint, so it goes where the admin pages already are, with your router and your sign-in around it.

A product where customers edit their own processes

Load a scheme by code per customer. The component is the same for everyone; the schemes differ. Set readOnly for the plan that may look but not edit.

Replacing a builder built on React Flow

Teams that drew Zapier-style flows on React Flow and now need commands, timers and roles move the drawing into the designer and keep the engine underneath it.

Support staff watching a request move

Pass a processId instead of a schemeCode and set readOnly. The page shows the running process with the current step highlighted, on the same diagram the analyst built.

What Free covers, and where Team starts

If you are a developer who needs a workflow builder in a React app, start with Workflow Engine Free. It has no cut-down editor. It covers the evaluation, the proof of concept and the learning, which is most of the way to a decision.

  • The full Workflow Designer, the same editor the paid embedded products get, and its React wrapper
  • 10 schemas and 4 execution threads; activities, transitions and commands are not limited
  • Perpetual, no license key, no time limit
  • Personal, non-commercial use: evaluation, a proof of concept, learning
  • The designer shows the Optimajet logo and "For non-commercial use only"

When the app goes to work for a business, you need a commercial edition. Workflow Engine Team costs $2,000 per product, perpetual, and lifts the caps on the same packages. There are no royalties and no per-execution fees. The full table, with the editions of Workflow Engine NEO for multi-tenant SaaS, is on the pricing page, and the free product has its own page.

What is still your job

Seven things to know before you plan the work. None of them is hidden in the sample; they are just easy to miss.

  • The Designer API is .NET: it runs on a server whatever the front end is. The route is 35 lines of C#, plus the CORS policy with your origins and the authentication you add the way you add it to any other route.
  • The canvas is sized from the window minus widthDiff and heightDiff. A layout with a header or a sidebar passes their sizes as the diffs; CSS on the container does nothing.
  • The component needs the DOM: render it on the client only. In Next.js that means a client component loaded without server rendering. We ran it on Vite, not on Next.js.
  • The wrapper brings the plain designer, jQuery and the stylesheet with it. A strict Content-Security-Policy uses the strict entry point and imports the stylesheet from the css entry point instead.
  • React 17.0.2 is the floor; 18 and 19 are in the peer range of 22.1.0.
  • Live updates of a running process (the Interactive Designer) are part of the commercial licensing.
  • The vendor's sample repository is on Create React App with React 18 and placeholders for the API address. The component code is the same; the scaffold is not one to start from today.

Common questions

Answers to common questions about using Workflow Designer in a React application.

  1. Is there a free React workflow builder?

    Yes. Workflow Engine Free includes the full Workflow Designer, and its React wrapper is available on npm. Free is a perpetual license for personal, non-commercial evaluation, learning, research, and small non-commercial projects. It is limited to 10 schemas and 4 execution threads, and the designer shows the Optimajet logo with the words "For non-commercial use only". Use a trial key to evaluate licensed features for a commercial proof of concept. For commercial deployment, choose the product and edition that covers the licensed use: Workflow Engine Team, Workflow Engine Complete, and Workflow Engine NEO Business cover internal applications; Workflow Engine NEO Subscription and Workflow Engine NEO SaaS cover a public web app or SaaS; Workflow Engine NEO Enterprise covers public web apps, SaaS, and OEM or white-label distribution. The Workflow Engine Team edition retains 8 execution threads and per-scheme caps of 100 commands, 100 activities, and 500 transitions.

  2. How do I add Workflow Designer to a React app?

    Run npm install @optimajet/workflow-designer-react, import its default export, and render <WorkflowDesigner /> with a designerConfig that holds apiurl and renderTo, and a schemeCode. The component creates its own div, loads the scheme when it mounts, and draws. One endpoint in your backend, the Designer API, answers its requests.

  3. Which React versions does the wrapper support?

    React 17.0.2 and later, 18 and 19: those are the peer dependencies of version 22.1.0. We ran the sample on React 19.3.0 with Vite 8.2.2.

  4. Does it work with TypeScript?

    Yes. The package ships its declarations: WorkflowDesignerProps, WorkflowDesignerConfig and InnerWorkflowDesigner, among others. A .tsx file gets the props checked. Our sample is JSX to stay short; nothing changes in a TSX file except the types.

  5. Does it work in Next.js?

    It is a browser component: it draws on a canvas and uses jQuery for its requests, so it needs the DOM. In Next.js, render it in a client component and load it with next/dynamic with server rendering turned off. We ran the sample on Vite; the Next.js path follows from what the component needs, it is not a run we made.

  6. React Flow or Workflow Designer?

    React Flow is an MIT-licensed React component for node-based editors and interactive diagrams. Its examples can add persistence, validation, or runner behavior, but they do not implement the Workflow Engine scheme and .NET runtime contract. Workflow Designer edits native Workflow Engine schemes that Workflow Runtime executes on .NET. Choose by the runtime contract you need.

  7. Can I put Save and Validate on my own buttons?

    Yes. Put a ref on the component and use getDesignerErrors() to validate the scheme and save() to persist it. The ref also supports scheme upload and download, clearing the canvas, existence checks, and refresh.

  8. Can the page show a running process?

    Yes. Configure the component with processId and readOnly to show a process snapshot with its current activity highlighted. Live updates require the Real-Time Tracking Plugin and its SignalR setup; the plugin has no separate license gate.

  9. Can it import and export BPMN?

    Current BPMN support is import-only and requires the BPMN Plugin with the appropriate license; BPMN export is not supported. Workflow Engine scheme XML can be downloaded and uploaded separately, and an uploaded scheme must be saved explicitly.

  10. Why does the browser report a CORS error?

    The designer calls the Designer API from the browser. If the app and API use different origins and the response has no matching CORS headers, the browser prevents the app from reading it. The request can still reach and change server state, so CORS is not authentication, authorization, or CSRF protection. The sample explicitly allows http://localhost:5173; demo.workflowengine.io sends no CORS headers. Configure explicit allowed origins and secure each operation, tenant, and scheme on the server.

Try it in an afternoon

Install Workflow Engine Free, run the endpoint, and render the component. When the designer shows your first scheme, you have the whole path from the canvas to a running process, on your own machine.

Optimajet's Integrate the Designer guide covers the Angular, Blazor and plain JavaScript paths next to this one, and the React integration from scratch tutorial builds a full backend with users, roles and an admin panel around the same designer.