Web Component
Use this approach when your target project is not a React app (Angular, Vue, plain HTML, or any other framework). Workflow Builder is wrapped in a standard custom element (<workflow-builder>) and consumed as an ES module or UMD bundle.
Implementation
Section titled “Implementation”1. Modify main.tsx
Section titled “1. Modify main.tsx”Replace the standard React root mount with a Web Component class:
import { StrictMode } from 'react';import * as ReactDOM from 'react-dom/client';
import { App } from './app/app';import './app/features/i18n';
class WorkflowBuilder extends HTMLElement { private root: ReactDOM.Root | null = null;
connectedCallback() { if (!this.root) { const container = document.createElement('div'); this.appendChild(container); this.root = ReactDOM.createRoot(container); this.root.render( <StrictMode> <App /> </StrictMode>, ); } }
disconnectedCallback() { if (this.root) { this.root.unmount(); this.root = null; } }}
customElements.define('workflow-builder', WorkflowBuilder);2. Update index.html
Section titled “2. Update index.html”<workflow-builder></workflow-builder>3. Configure Vite for library mode
Section titled “3. Configure Vite for library mode”// vite.config.mtsbuild: { lib: { entry: path.resolve(__dirname, './src/main.tsx'), name: 'WorkflowBuilder', fileName: (format) => `workflow-builder.${format}.js`, formats: ['es', 'umd'], }, outDir: 'dist/package',},4. Create an npm package
Section titled “4. Create an npm package”After building, add a package.json inside dist/package/:
{ "name": "workflow-builder", "version": "1.0.0", "main": "workflow-builder.umd.js", "module": "workflow-builder.es.js", "style": "frontend.css", "peerDependencies": { "react": "^19.1.0", "react-dom": "^19.1.0" }, "files": ["workflow-builder.umd.js", "workflow-builder.es.js", "frontend.css"]}Using in a host application
Section titled “Using in a host application”Drop the built files into your project and use the custom element anywhere:
<script src="workflow-builder.es.js" type="module"></script><link rel="stylesheet" href="frontend.css" />
<workflow-builder></workflow-builder>Works in React, Angular, Vue, or plain HTML. Note that React and ReactDOM are listed as peer dependencies, so the host application must provide them.
Style encapsulation
Section titled “Style encapsulation”The web component renders in the light DOM (no Shadow DOM). This means the host page’s CSS may affect Workflow Builder’s styles and vice versa. If you need full style isolation, wrap the component in a Shadow DOM root:
connectedCallback() { if (!this.root) { const shadow = this.attachShadow({ mode: 'open' }); const container = document.createElement('div'); shadow.appendChild(container); this.root = ReactDOM.createRoot(container); this.root.render( <StrictMode> <App /> </StrictMode>, ); }}Note that when using Shadow DOM, you must inject Workflow Builder’s stylesheet into the shadow root rather than the document head.
Alternatives considered
Section titled “Alternatives considered”| Approach | Pros | Cons |
|---|---|---|
| Web Component | Framework-agnostic, standardized API | Requires wrapper setup |
| iFrame | Full isolation, no conflicts | Limited interaction, styling constraints |
| Module Federation | Runtime dependency sharing | Requires Webpack support in host |
| Framework adapters (react2angular, etc.) | Deep integration | Per-framework maintenance burden |