Configuration
Options for dimahForm(), createFormClient(), useFormResponse, and ResponseStore.
Options for the server instance, the React client, the fill hook, and a custom database adapter.
dimahForm(config)
The primary server instance initializer from @dimah-form/server. database is required. @dimah-form/db is not — memoryAdapter() ships in @dimah-form/server.
import { dimahForm } from "@dimah-form/server";
export const form = dimahForm({
database: memoryAdapter(),
forms: { ... },
basePath: "/api/form",
});Configuration Options
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
database | ResponseStore | Yes | — | Persistence adapter (memoryAdapter(), db(formDb) from @dimah-form/db, or a custom ResponseStore). |
forms | Record<string, FormDefinitionInput> | No | {} | Catalog of code-authored forms created with defineForm(). Feeds $Infer. |
fieldTypes | FieldTypeDefinition[] | No | [] | Custom field type definitions created with defineFieldType(). |
basePath | string | No | "/api/form" | Base path prefix for HTTP route mounting. |
guard | DimahFormGuard | No | undefined | Security callback executed before every query or mutation. |
hooks | DimahFormHooks | No | {} | Pre-write (onStart, onDraft, onSubmit) and post-write (afterSubmit, afterDraft, afterDelete) lifecycle hooks. |
validateAnswers | AnswersValidator | No | undefined | Custom cross-field validation function running on submit. |
plugins | DimahFormPlugin[] | No | [] | Server plugins created with definePlugin(). |
metaSchema | DimahFormMetaSchema | No | undefined | Custom Zod schemas for validating meta dictionaries on forms and fields. |
createFormClient<T>(options)
Initializes the typed client runtime from @dimah-form/react.
import { createFormClient } from "@dimah-form/react";
import type { Form } from "@/lib/form";
export const formClient = createFormClient<Form>({
basePath: "/api/form",
});Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
basePath | string | "/api/form" | Relative URL path prefix matching the server's basePath. |
baseURL | string | undefined | Absolute URL prefix (e.g., "https://api.example.com/api/form"). Overrides basePath. |
credentials | RequestCredentials | "same-origin" | Fetch credentials policy (e.g. "include" for cross-origin cookies). |
headers | HeadersInit | (() => MaybePromise<HeadersInit>) | undefined | Static headers or dynamic header generator for auth tokens. |
fieldTypes | FieldTypeDefinition[] | [] | Custom field types matching the server configuration. |
plugins | DimahFormClientPlugin[] | [] | Companion client plugins created with defineClientPlugin(). |
fetch | typeof fetch | globalThis.fetch | Custom fetch implementation for SSR or testing harnesses. |
useFormResponse(options)
Headless React hook for managing fill sessions.
Options
| Option | Type | Required | Description |
|---|---|---|---|
snapshot | FormSnapshot | Yes | Form definition snapshot (retrieved from server). |
response | ResponseRecord | No | Existing response row to edit or view. |
respondentId | string | (() => string) | No | User identifier for draft ownership. |
resume | boolean | No | If true, reconnects to the user's latest draft on first write. |
autosave | boolean | { debounceMs?: number } | No | Enables debounced background draft saving (default debounce: 600ms). |
validate | "submit" | "change" | No | "submit" (default) or "change" (real-time validation on edit). |
onStarted | (record: ResponseRecord) => void | No | Callback invoked after startResponse completes. |
onSaved | (record: ResponseRecord) => void | No | Callback invoked after saveDraft completes. |
onSubmitted | (record: ResponseRecord) => void | No | Callback invoked after submitResponse completes. |
onReopened | (record: ResponseRecord) => void | No | Callback invoked after reopenResponse completes. |
onAbandoned | (record: ResponseRecord) => void | No | Callback invoked after abandonResponse completes. |
The ResponseStore Interface
Any database adapter passed to dimahForm({ database }) must satisfy the following interface:
interface ResponseStore {
// Form Definitions
getForm(idOrSlug: string): MaybePromise<FormSnapshot | undefined>;
saveForm(
form: FormSnapshot,
options?: { expectedUpdatedAt?: string },
): MaybePromise<void>;
deleteForm(id: string): MaybePromise<void>;
listForms(query?: {
status?: FormStatus;
limit?: number;
offset?: number;
}): MaybePromise<{
forms: FormSnapshot[];
limit: number;
offset: number;
nextOffset: number | null;
}>;
// Response Sessions
create(row: ResponseRecord): MaybePromise<void>;
get(id: string): MaybePromise<ResponseRecord | undefined>;
save(
row: ResponseRecord,
options?: { expectedUpdatedAt?: string },
): MaybePromise<void>;
delete(id: string): MaybePromise<void>;
listResponses(query?: ListResponsesQuery): MaybePromise<{
responses: (ResponseRecord | ResponseSummary)[];
limit: number;
offset: number;
nextOffset: number | null;
}>;
// Draft Helpers
findLatestDraft(query: {
formId: string;
respondentId: string;
}): MaybePromise<ResponseRecord | undefined>;
getOrCreateDraft(row: ResponseRecord): MaybePromise<ResponseRecord>;
}