npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

qp-workflow-react

v1.0.5

Published

React components and hooks for visual workflow design and execution. Pairs with Chd.Workflow .NET backend.

Readme

qp-workflow-react

npm TypeScript React License: MIT

qp-workflow-react is the React + TypeScript companion package for the Chd.Workflow backend engine. It provides ready-to-use UI pieces for both workflow design and workflow execution.

The package is designed for teams that want to move quickly without rebuilding workflow UI from scratch for every project.

It includes:

  • a visual workflow designer,
  • a runtime workflow runner,
  • a TypeScript API client,
  • React hooks for custom experiences,
  • localization support,
  • external form helpers,
  • an admin modal for workflow notification settings.

Although it pairs naturally with Chd.Workflow, the client and components can also work with another backend if the same REST contract is respected.


Table of Contents


Why this package exists

A workflow UI is usually more than just a form.

A real workflow screen often needs to:

  • load the current workflow state,
  • render fields based on the current node,
  • validate inputs,
  • show available transitions,
  • support confirmation or comment requirements,
  • handle guard failures,
  • load dropdown options from the backend,
  • support external forms,
  • support multiple languages,
  • give designers a way to edit the workflow visually.

If every project builds this from zero, teams spend a lot of time repeating the same work.

qp-workflow-react solves that by packaging the repeated parts into reusable building blocks.

This lets teams focus on:

  • business logic,
  • design customization,
  • backend actions and rules,
  • project-specific workflows.

Main capabilities

Visual workflow design

TreeDesigner provides a visual tree-based editing experience.

Runtime workflow execution

WorkflowRunner renders the active node, fields, and available actions.

Custom workflow UX with hooks

The React hook export lets you build your own UI while reusing state loading and transition logic.

API abstraction

WorkflowClient wraps the REST API in a simple TypeScript class.

External form support

Helpers make it easier to connect non-React or external pages to the same workflow.

Localization

English and Turkish translations are available out of the box.

Notification admin UI

A ready modal exists for notification settings management when the backend exposes those endpoints.


Installation

npm install qp-workflow-react

Peer dependencies:

  • react >= 18
  • react-dom >= 18

This package builds around a backend that follows the Chd.Workflow REST contract.


Package exports

The package currently exports the following main items:

Core API and types

  • WorkflowClient
  • WorkflowClientError
  • all public workflow types from src/types

React hook export

  • useWorkflowReact

Designer exports

  • TreeDesigner
  • WorkflowDesigner
  • createDefaultWorkflowDefinition

Runtime exports

  • WorkflowRunner

External form helpers

  • buildExternalFormUrl
  • parseWorkflowParams
  • useWorkflowParams
  • useWorkflowExternalForm

Host/admin export

  • WorkflowHostNotificationSettingsModal

Localization exports

  • LocaleProvider
  • useLocale
  • getLocale
  • locales
  • locale-related types

Quick start

A basic end-to-end scenario usually has two parts.

1. Design a workflow

import { TreeDesigner } from 'qp-workflow-react';

<TreeDesigner
  apiUrl="http://localhost:5035/api/workflow"
  initialDefinitionId="leave-request"
  locale="en"
  enableFormEditor
  onSaved={(definition) => console.log('saved', definition.id)}
/>

2. Run a workflow instance

import { WorkflowRunner, WorkflowClient } from 'qp-workflow-react';

const client = new WorkflowClient({
  apiUrl: 'http://localhost:5035/api/workflow'
});

const instance = await client.createInstance('leave-request', {
  employeeId: '123'
});

<WorkflowRunner
  apiUrl="http://localhost:5035/api/workflow"
  instanceId={instance.id}
  locale="en"
  theme="dark"
  onCompleted={(result) => console.log('completed', result.id)}
/>

Main components

TreeDesigner

TreeDesigner is the main visual workflow editor.

It is useful when you want to:

  • create nodes visually,
  • manage transitions,
  • choose action handlers,
  • choose guard handlers,
  • set allowed roles/groups,
  • edit form fields,
  • save definitions through the REST API.

Basic usage

<TreeDesigner
  apiUrl="http://localhost:5035/api/workflow"
  initialDefinitionId="leave-request"
  locale="en"
  enableFormEditor
  onSaved={(definition) => console.log(definition.id)}
/>

Main props

| Prop | Type | Description | |---|---|---| | apiUrl | string | Base workflow API URL | | initialDefinitionId? | string | Definition id to load first | | onSaved? | (saved) => void | Called after successful save | | locale? | 'en' \| 'tr' | UI language | | enableFormEditor? | boolean | Enables field editing UI |

Practical notes

  • The component loads action metadata from /actions.
  • It loads guard metadata from /guards.
  • It loads participant group data from /admin/participant-groups.
  • It can create a default definition if the requested definition does not exist.

This makes it suitable for both new workflow design and editing existing definitions.


WorkflowRunner

WorkflowRunner is the runtime execution component.

It is useful when you want a ready-made UI that:

  • loads the workflow state,
  • renders the current step fields,
  • validates values,
  • displays available transitions,
  • handles comments and confirmations,
  • supports dark and light themes,
  • refreshes state after transitions.

Basic usage

<WorkflowRunner
  apiUrl="http://localhost:5035/api/workflow"
  instanceId="instance-abc123"
  locale="en"
  theme="dark"
  onTransition={(action, state) => console.log(action, state)}
  onCompleted={(instance) => console.log(instance.id)}
  onError={(error) => console.error(error)}
/>

Main props

| Prop | Type | Description | |---|---|---| | apiUrl | string | Base workflow API URL | | instanceId | string | Instance to render | | theme? | 'dark' \| 'light' | Runner theme | | locale? | 'en' \| 'tr' | UI language | | debug? | boolean | Shows extra debug data | | onCompleted? | (instance) => void | Called when the workflow reaches completion | | onTransition? | (action, newState) => void | Called after successful transition | | onError? | (error) => void | Called on workflow errors | | loadingComponent? | ReactNode | Custom loading UI | | errorComponent? | (error, retry) => ReactNode | Custom error UI | | completedComponent? | (node, instance) => ReactNode | Custom completion UI | | className? | string | Custom CSS class | | style? | CSSProperties | Inline style override |

Built-in behavior

The runner already handles many common tasks:

  • loading GET /instances/{id}/state,
  • rendering fields by type,
  • preserving and updating form values,
  • showing validation errors,
  • calling transition endpoints,
  • handling requiresConfirmation,
  • handling requiresComment,
  • handling guard failures returned by the backend,
  • loading field options when needed.

This is often enough for production usage without writing a custom runtime screen.


WorkflowDesigner

WorkflowDesigner is a more form-oriented design alternative.

Use it if you want a simpler editing style instead of the main tree-first visual layout.

import { WorkflowDesigner } from 'qp-workflow-react';

<WorkflowDesigner
  apiUrl="http://localhost:5035/api/workflow"
  initialDefinitionId="leave-request"
  onSaved={(definition) => console.log(definition.id)}
/>

WorkflowHostNotificationSettingsModal

This modal is intended for host/admin screens.

It communicates with:

  • GET /admin/notification-settings
  • PUT /admin/notification-settings

It helps manage workflow notification-related settings such as:

  • SMTP host,
  • SMTP port,
  • SMTP user,
  • password presence,
  • from email,
  • SSL usage,
  • subject and body templates,
  • group member resolution SQL,
  • email column name.

Example

import { WorkflowHostNotificationSettingsModal } from 'qp-workflow-react';

<WorkflowHostNotificationSettingsModal
  open={open}
  onClose={() => setOpen(false)}
  apiUrl="http://localhost:5035/api/workflow"
  locale="en"
/>

A 503 response usually means the backend host has not enabled the required persistence service for this admin area.


Hook usage

The package exports the React hook as useWorkflowReact.

This hook is useful when:

  • WorkflowRunner is too opinionated for your screen,
  • you want your own layout,
  • you still want to reuse workflow loading and transition logic.

Example

import { useWorkflowReact, WorkflowClient } from 'qp-workflow-react';

const client = new WorkflowClient({ apiUrl: 'http://localhost:5035/api/workflow' });

function CustomRunner({ instanceId }: { instanceId: string }) {
  const {
    state,
    currentNode,
    fields,
    availableActions,
    values,
    errors,
    isLoading,
    error,
    setValue,
    transition,
    reload,
  } = useWorkflowReact({ client, instanceId });

  if (isLoading) return <p>Loading...</p>;
  if (error) return <p>{error.message}</p>;

  return (
    <div>
      <h2>{currentNode?.title ?? currentNode?.name}</h2>

      {fields.map(field => (
        <div key={field.name}>
          <label>{field.label ?? field.name}</label>
          <input
            value={String(values[field.name] ?? '')}
            onChange={e => setValue(field.name, e.target.value)}
          />
          {errors[field.name] && <div>{errors[field.name]}</div>}
        </div>
      ))}

      {availableActions.map(action => (
        <button key={action.id} onClick={() => transition(action.action)}>
          {action.label ?? action.action}
        </button>
      ))}

      <button onClick={() => reload()}>Reload</button>
    </div>
  );
}

What the hook returns

The hook exposes:

  • current workflow state,
  • current node,
  • fields,
  • available actions,
  • history,
  • breadcrumb,
  • form values,
  • validation errors,
  • loading/error state,
  • helpers such as setValue, setValues, transition, validate, reload, createInstance, cancel.

This is a good option when you need a custom UI but do not want to rebuild the workflow data layer yourself.


Client API

WorkflowClient is a TypeScript wrapper around the workflow REST API.

It is framework-agnostic at the data level and can be used outside the ready React components.

Basic setup

import { WorkflowClient } from 'qp-workflow-react';

const client = new WorkflowClient({
  apiUrl: 'http://localhost:5035/api/workflow',
  headers: {
    'X-Tenant-Id': 'tenant-1'
  },
  onError: (error) => console.error(error)
});

Helpful runtime methods

client.setAuthToken('Bearer token');
client.clearAuthToken();
client.setApiUrl('https://example.com/api/workflow');

Main methods

Definitions

  • getDefinitions(tenantId?)
  • getDefinition(id)
  • createDefinition(definition)
  • updateDefinition(id, definition)
  • deleteDefinition(id)

Instances

  • getInstance(id)
  • getState(instanceId)
  • createInstance(definitionId, data?, userId?)
  • transition(instanceId, action, data?, userId?, comment?)
  • validate(instanceId, data)
  • getFieldOptions(instanceId, fieldName)
  • cancel(instanceId, request?)

Admin

  • getNotificationAdminSettings()
  • updateNotificationAdminSettings(body)

Error model

The client throws WorkflowClientError.

Important properties include:

  • message
  • status
  • errors?

This is useful when you want to surface backend validation details directly in your UI.


TypeScript model overview

The package exports a broad public type model that mirrors the backend contract.

Important examples include:

Enums and union types

  • NodeType
  • FieldType
  • FormType
  • WorkflowStatus
  • RuleType
  • ButtonStyle

Core models

  • FieldOption
  • Field
  • Transition
  • Rule
  • RuleMapping
  • Node
  • WorkflowDefinition
  • WorkflowInstance
  • HistoryEntry
  • WorkflowState

Metadata models

  • WorkflowActionInfo
  • WorkflowInputProperty
  • WorkflowOutputProperty
  • WorkflowGuardInfo
  • WorkflowRuleInfo

Client models

  • WorkflowClientOptions
  • CreateInstanceRequest
  • TransitionRequest
  • CancelRequest
  • ValidationResult
  • WorkflowNotificationAdminSettings

This makes the package pleasant to use in TypeScript-heavy projects because both component usage and API usage remain strongly typed.


Field system and validation

The field system supports both backend-aligned field types and frontend-friendly validation behavior.

Supported field types

Current public field type support includes:

  • Text
  • TextArea
  • Number
  • Decimal
  • Date
  • DateTime
  • Time
  • Checkbox
  • Radio
  • Dropdown
  • MultiSelect
  • File
  • Image
  • RichText
  • Hidden
  • Email
  • Phone
  • Currency

Validation behavior

The runtime supports practical validation such as:

  • required checks,
  • min and max values,
  • max length,
  • regex validation,
  • type-based validation for number/date/email/phone/currency.

Field options

For selectable fields, options can come from:

  • static field configuration,
  • backend field option endpoints.

Visibility support

The field model also includes support for visibility expressions and guard-related visibility metadata.

This helps advanced forms stay dynamic without requiring every project to write custom visibility logic from zero.


External form integration

External forms are useful when the workflow step should be completed in another page or system.

Examples:

  • a legacy MVC/Razor page,
  • an older admin form,
  • a third-party hosted screen,
  • a specialized custom data entry module.

Helper: buildExternalFormUrl

This helper creates a URL with workflow context parameters.

Typical values added include:

  • workflowInstanceId
  • workflowNodeId
  • workflowDefinitionId
  • workflowActions
  • workflowCallback

Helper: parseWorkflowParams

Reads workflow context from query string.

Hook: useWorkflowParams

Convenient React wrapper over parseWorkflowParams().

Hook: useWorkflowExternalForm

A higher-level helper for external form pages.

It helps with:

  • reading workflow context,
  • calling transition APIs,
  • managing loading and error state,
  • returning to the callback URL after submission.

Example

import { useWorkflowExternalForm } from 'qp-workflow-react';

function ExternalApprovalPage() {
  const workflow = useWorkflowExternalForm({
    apiUrl: '/api/workflow'
  });

  async function submitApprove() {
    await workflow.submit('approve', {
      note: 'Approved from external page'
    });
  }

  return (
    <div>
      <button onClick={submitApprove} disabled={workflow.loading}>
        Approve
      </button>
      {workflow.error && <p>{workflow.error}</p>}
      {workflow.success && <p>{workflow.success}</p>}
    </div>
  );
}

This is especially useful when not every workflow step should stay inside the main React runner screen.


Localization

The package currently includes English and Turkish locale support.

Basic usage

import { getLocale } from 'qp-workflow-react';

const t = getLocale('en');
console.log(t.common.save);

Provider-based usage

import { LocaleProvider } from 'qp-workflow-react';

<LocaleProvider locale="tr">
  <App />
</LocaleProvider>

Supported locale codes

  • 'en'
  • 'tr'

Where localization is used

Localization is used in areas such as:

  • common labels,
  • runner UI,
  • designer UI,
  • validation messages,
  • action labels,
  • host notification settings modal.

This makes the package easier to adopt in multilingual internal systems.


Backend contract

This package is designed around the Chd.Workflow backend contract.

Expected endpoints

| Method | Path | |---|---| | GET | /definitions | | GET | /definitions/{id} | | POST | /definitions | | PUT | /definitions/{id} | | DELETE | /definitions/{id} | | GET | /instances/{id} | | GET | /instances/{id}/state | | GET | /instances/{id}/field-options/{fieldName} | | POST | /instances | | POST | /instances/{id}/transition | | POST | /instances/{id}/validate | | POST | /instances/{id}/cancel | | GET | /actions | | GET | /actions/grouped | | GET | /guards | | GET | /rules | | GET | /rules/grouped | | GET | /rules/{name} | | GET | /admin/notification-settings | | PUT | /admin/notification-settings | | GET | /admin/participant-groups |

JSON style expectations

The package assumes a backend that behaves similarly to the current Chd.Workflow implementation.

In practice, that means:

  • camelCase JSON is preferred,
  • enum values should be serialized in a compatible way,
  • error payloads should include error and optionally errors.

If you build your own compatible backend, the React package can still be reused.


Build and publish

Important package information from the current project setup:

  • package name: qp-workflow-react
  • build tool: tsup
  • output: dist
  • peer dependencies: React 18+

Common commands

npm install
npm run build
npm run dev
npm run typecheck

Publish notes

When publishing, keep these fields correct in package.json:

  • name
  • version
  • description
  • main
  • module
  • types
  • repository
  • license
  • files

These details matter because the package is intended to be consumed as a reusable npm library, not only as a local project.


Troubleshooting

Designer cannot load actions or guards

Check that the backend API is running and that:

  • /actions works,
  • /guards works,
  • CORS is configured correctly,
  • the API URL is correct.

Participant groups are empty

Check /admin/participant-groups. If the backend does not implement or register participant directory support, the list may be empty.

Transition fails with validation messages

The backend may be returning field-level validation details. Catch WorkflowClientError and inspect error.errors.

Guard failure is returned from the backend

A denied guard usually comes back with code = "GUARD_FAILED". This means the transition was blocked intentionally by workflow logic.

Notification settings modal returns not available

A 503 usually means the backend host has not enabled the notification admin settings service.

External form flow does not return properly

Check:

  • query string parameters,
  • callback URL value,
  • transition call success,
  • whether the page is opened in the same window or inside an iframe.

License

MIT License. See LICENSE.


For the backend package details, read Chd.Workflow/README.md.