Context
The current form builder is built on @bpmn-io/form-js. Our assessment of its production readiness
is recorded in claude/form-editor-assessment.md; in short, the ceiling comes down to three things
that cannot be fixed by extending the library:
- Data integration. The only source of options is process variables
(values / valuesKey / valuesExpression). No REST, no reference data, no autocomplete —
this is a deliberate form-js architectural decision: "a form does not talk to the network."
- Logic and validation. Only
conditional.hide; no conditional requiredness, no async or
server-side validation, no API for registering your own validators, and error texts are hardcoded
in English.
- The editor as a product for a business analyst. No i18n (issue #77 has been open since 2021),
no way to add your own palette group, custom fields have to be written in Preact, and the
bpmn.io watermark cannot be removed under the license.
On top of that, the pace of development: since documentPreview (1.13.0, December 2024) form-js has
not gained a single new field type — the project is in maintenance mode.
We need to check whether FormEngine (Optimajet) closes these gaps:
demo builder — https://formbuilder.formengine.io/, documentation — https://formengine.io/documentation/,
sources — https://github.com/optimajet/formengine.
Questions to answer
1. What are the advantages over the BPMN.IO editor (form-js)?
Verify and confirm against the code / demo:
- Component set: is there an editable table (Data Grid), a multi-step form / wizard, input masks,
signature, rich text, file upload. Which of these are in the free core and which only come with
the paid sets.
- Extensibility: registering your own components (
define(Component, 'Type') + property annotations),
whether they appear in the palette automatically, and whether you can add your own group/category.
- Validation: confirm that validators are asynchronous, that there are form-level validators
(formValidators), cross-field checks, custom error texts and their localization (Fluent).
This is exactly the form-js pain point currently patched by our Validator fork.
- i18n of the editor itself and of the forms: how many languages each tier includes, whether Russian
localization is available out of the box, and how completely the palette and the properties panel
are localized.
- No watermark at runtime (unlike
.bjs-powered-by).
- Pace of development: compare with form-js (FormEngine's current major version is 10.x with regular
releases; form-js has had no new field types for 20 months).
2. What are the drawbacks and risks?
- UI kit. The official component sets are Material UI, Mantine, React Suite, shadcn/ui;
AntD is in development.
- The form schema is a tree, not a flat list. This diverges from the current form-js format
(components[]) and from the form-IR we have been discussing. Assess what this means for the
compiler and for AI-copilot form generation (structured outputs over a tree are harder and less
reliable).
- Code inside the schema. Computed properties and code validators are stored in JSON as the body
of a JS function (computeType: "function", fnSource). This means executing arbitrary JS from
the database: questions of security (eval/CSP), review, diffs and migrations.
3. How does working with data happen?
Investigate and document as a diagram:
- Input:
initialData on <FormViewer>, mapping by field keys / dataKey, reactivity.
- Changes:
onFormDataChange → IFormData { data, errors }; imperative access via viewerRef.formData.
- Validation:
getValidationResult() vs formData.errors, the order "field validators → form validators".
- Submission: our own code/actions — there is no built-in transport; the form hands back an object
and everything after that is our responsibility.
- Key question: the data contract. What ends up in the result for hidden, disabled and computed
fields, and how numbers, dates and files are serialized. This is the main risk of any renderer
change (see form-renderer-review.md §R1) — we need a diff of submit data against the current
form-js viewer on identical forms.
- Reference data: is there a first-class mechanism for loading options from REST and for dependent
lookups ("region → city"), or does that require a custom component and a custom action. This is the
main reason for the whole investigation — the answer must be precise and backed by a working example.
- Mapping onto Camunda/Operaton process variables (
type, valueInfo) and onto file storage.
4. Where should forms that are executed on the front end be stored?
- In the designer, storage goes through the
IFormStorage interface (getForm, saveForm,
getFormNames, removeForm), which is implemented by the consumer; by default there is no
storage at all, only JSON import/export. In other words, we choose where forms live.
5. What license does it use? Can it be used in a commercial product?
Check the licensing:
- Can it be used in commercial products?
- Is there a paid edition? How do the editions differ?
Scope of work
- Study the documentation and the demo builder, and run 2–3 real forms through it.
- Build a minimal PoC (separate branch / sandbox, not in the main build):
FormViewer from the MIT core in a test application;
- one custom field on antd (for example, a lookup autocomplete that loads options over REST);
- an async validator that calls the server;
IFormStorage on top of a stub of our API;
- a diff of submit data against the current form-js viewer on the same form.
Links
Context
The current form builder is built on
@bpmn-io/form-js. Our assessment of its production readinessis recorded in
claude/form-editor-assessment.md; in short, the ceiling comes down to three thingsthat cannot be fixed by extending the library:
(
values/valuesKey/valuesExpression). No REST, no reference data, no autocomplete —this is a deliberate form-js architectural decision: "a form does not talk to the network."
conditional.hide; no conditional requiredness, no async orserver-side validation, no API for registering your own validators, and error texts are hardcoded
in English.
no way to add your own palette group, custom fields have to be written in Preact, and the
bpmn.io watermark cannot be removed under the license.
On top of that, the pace of development: since
documentPreview(1.13.0, December 2024) form-js hasnot gained a single new field type — the project is in maintenance mode.
We need to check whether FormEngine (Optimajet) closes these gaps:
demo builder — https://formbuilder.formengine.io/, documentation — https://formengine.io/documentation/,
sources — https://github.com/optimajet/formengine.
Questions to answer
1. What are the advantages over the BPMN.IO editor (form-js)?
Verify and confirm against the code / demo:
signature, rich text, file upload. Which of these are in the free core and which only come with
the paid sets.
define(Component, 'Type')+ property annotations),whether they appear in the palette automatically, and whether you can add your own group/category.
(
formValidators), cross-field checks, custom error texts and their localization (Fluent).This is exactly the form-js pain point currently patched by our
Validatorfork.localization is available out of the box, and how completely the palette and the properties panel
are localized.
.bjs-powered-by).releases; form-js has had no new field types for 20 months).
2. What are the drawbacks and risks?
AntD is in development.
(
components[]) and from theform-IRwe have been discussing. Assess what this means for thecompiler and for AI-copilot form generation (structured outputs over a tree are harder and less
reliable).
of a JS function (
computeType: "function",fnSource). This means executing arbitrary JS fromthe database: questions of security (
eval/CSP), review, diffs and migrations.3. How does working with data happen?
Investigate and document as a diagram:
initialDataon<FormViewer>, mapping by field keys /dataKey, reactivity.onFormDataChange→IFormData { data, errors }; imperative access viaviewerRef.formData.getValidationResult()vsformData.errors, the order "field validators → form validators".and everything after that is our responsibility.
fields, and how numbers, dates and files are serialized. This is the main risk of any renderer
change (see
form-renderer-review.md§R1) — we need a diff of submit data against the currentform-js viewer on identical forms.
lookups ("region → city"), or does that require a custom component and a custom action. This is the
main reason for the whole investigation — the answer must be precise and backed by a working example.
type,valueInfo) and onto file storage.4. Where should forms that are executed on the front end be stored?
IFormStorageinterface (getForm,saveForm,getFormNames,removeForm), which is implemented by the consumer; by default there is nostorage at all, only JSON import/export. In other words, we choose where forms live.
5. What license does it use? Can it be used in a commercial product?
Check the licensing:
Scope of work
FormViewerfrom the MIT core in a test application;IFormStorageon top of a stub of our API;Links