Introduction
A headless questionnaire engine. You own the UI. The library owns snapshots, drafts, and submit validation.
dimah-form is a backend-first questionnaire engine. It freezes the form definition onto every response, validates answers against that snapshot, and gives React a thin fill-session hook. It does not render fields, ship widgets, or own your auth.
- React ClientuseFormResponse + your widgets
- HTTP HandlerdimahForm() + your guard
- PersistenceSnapshots and responses
When to use it
Use it when you need typed questionnaires with drafts and server-side validation, and you already have a design system.
Skip it if you want a form renderer, a visual builder, or hosted survey SaaS.
The problems it is built around:
- Schema drift — an admin can change a live form while someone is still filling a draft. dimah-form validates against the snapshot taken at start, not the live definition.
- Drafts — respondents leave, switch devices, or drop packets. Drafts save incrementally, with
updatedAtcompare-and-swap so two tabs do not silently overwrite each other. - Headless validation — you render with Tailwind, shadcn/ui, or plain HTML. The server still checks required visible fields against the frozen snapshot.
Packages
@dimah-form/core
↓
@dimah-form/server ← @dimah-form/db (optional)
│
@dimah-form/react| Package | Where | What you import it for |
|---|---|---|
@dimah-form/core | Shared | Protocol types, field validators, error codes. Server and React both depend on it. |
@dimah-form/server | Node / Edge | dimahForm(), HTTP adapters, form.api, memoryAdapter(). |
@dimah-form/react | Browser ("use client") | createFormClient(), useFormResponse(), field helpers. |
@dimah-form/db | Server | Optional. Production SQL adapter via FumaDB. |
How to read these docs
Start with the Quickstart if you want a working Next.js form. Read Architecture and Snapshots when you need the model, not just the copy-paste.
Quickstart
Install, define a form, mount the handler, and render a fill UI.
Architecture
Package boundaries, data flow, and the request pipeline.
Forms
defineForm, field rules, showWhen, and $Infer.
React Client
useFormResponse: visibility, drafts, and submit.
After that, pick the layer you are implementing:
- Client — React and Widgets
- Backend — Server, Database, Auth
- Extending — Custom Fields and Plugins
- Reference — Configuration, Field Types, Protocol, Errors