Your business rules don't belong in code
How it works
Domain experts design the rules. Developers consume the spec. No one writes boilerplate.
Define
Domain experts describe rules conversationally. AI generates a formal Forma spec with FEEL expressions, validation, and computed fields.
Consume
Developers fetch the spec via API. Render with forma-react or build custom UI. Validate server-side with a single POST.
Evolve
Rules change without deploys. Version history, instant publishing. Analytics on how forms perform.
One spec, any renderer
Domain experts define rules. The platform generates a spec. Developers fetch it via API — use our React renderer or build your own.
Domain Expert
Describes rules in plain language
Formidable AI
Generates formal spec
Forma Spec
JSON + FEEL expressions
forma-react
npm package — zero UI code
REST API
Validate & compute from any language
Custom UI
Read the spec, render your way
// Install
npm install @fogpipe/forma-react @fogpipe/forma-core
// Fetch the published spec
const spec = await fetch(
"https://api.formidable.software/f/loan-app"
).then(r => r.json());
// ─── Option A: forma-react (zero UI code) ───
import { FormaRenderer } from "@fogpipe/forma-react";
<FormaRenderer
spec={spec}
onSubmit={handleSubmit}
/>
// ─── Option B: Build your own UI ───
// The spec is just JSON — read it, render however
spec.fields.forEach(field => {
// field.type, field.label, field.validation...
});
// Either way: validate server-side
const result = await fetch(
"https://api.formidable.software/f/loan-app/validate",
{ method: "POST", body: JSON.stringify(formData) }
);Why not just code it?
You could. But every rule change becomes a deploy, and every deploy is a risk.
The logic engine
One spec powers validation, computation, and orchestration. Your codebase stays clean.
Validate
Send data, get pass/fail with field-level errors. Same rules on frontend and backend.
const res = await fetch(
"/api/f/loan-app/validate",
{
method: "POST",
body: JSON.stringify({
income: 85000,
credit_score: 720,
}),
}
);
// → { valid: true, errors: [] }Compute
Computed outputs from FEEL expressions: scores, totals, eligibility, risk tiers. No logic in your codebase.
const res = await fetch(
"/api/f/loan-app/evaluate",
{
method: "POST",
body: JSON.stringify({
income: 85000,
debt: 29750,
}),
}
);
// → { risk_tier: "low", max_loan: 340000 }Orchestrate
Coming soonWorkflow layer: on submit, validate, route based on outcomes, trigger integrations, send notifications, chain to next form.
// Coming soon
// on_submit:
// - validate
// - if outcome = "approved"
// → notify(slack, #approvals)
// → chain(onboarding-form)
// - if outcome = "rejected"
// → notify(email, applicant)Shape the developer platform
We're building the API-first form logic platform. Get early access and help us shape it.
Want a guided walkthrough?
See how the platform can streamline form logic for your team. We'll walk you through a live demo tailored to your use case.