{"id":31070884,"url":"https://github.com/wildhoney/formikate","last_synced_at":"2026-05-19T14:34:15.622Z","repository":{"id":313269914,"uuid":"1050021546","full_name":"Wildhoney/Formikate","owner":"Wildhoney","description":"🪚 Lightweight form builder for React that lets you dynamically render form fields from validation schemas, manage multi-step flows, and simplify validation handling.","archived":false,"fork":false,"pushed_at":"2025-09-09T22:03:33.000Z","size":2162,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-10T01:08:07.342Z","etag":null,"topics":["form","form-builder","form-builder-using-react","formik","formik-form","formik-inputs","formik-schema","formik-validation","formik-yup","forms","validation","validation-library","yup","zod"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Wildhoney.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-03T20:42:22.000Z","updated_at":"2025-09-09T22:03:36.000Z","dependencies_parsed_at":"2025-09-10T01:08:19.756Z","dependency_job_id":"2a4d9746-1748-42e9-a133-4d313790761f","html_url":"https://github.com/Wildhoney/Formikate","commit_stats":null,"previous_names":["wildhoney/schematik","wildhoney/formikate"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/Wildhoney/Formikate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wildhoney%2FFormikate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wildhoney%2FFormikate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wildhoney%2FFormikate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wildhoney%2FFormikate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Wildhoney","download_url":"https://codeload.github.com/Wildhoney/Formikate/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wildhoney%2FFormikate/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275333311,"owners_count":25446100,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-15T02:00:09.272Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["form","form-builder","form-builder-using-react","formik","formik-form","formik-inputs","formik-schema","formik-validation","formik-yup","forms","validation","validation-library","yup","zod"],"created_at":"2025-09-15T23:03:32.054Z","updated_at":"2026-05-19T14:34:15.615Z","avatar_url":"https://github.com/Wildhoney.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# \u003cimg src=\"media/icon.png\" alt=\"Formikate\" width=\"32\" height=\"32\" /\u003e Formikate\n\n[![Checks](https://github.com/Wildhoney/Formikate/actions/workflows/checks.yml/badge.svg)](https://github.com/Wildhoney/Formikate/actions/workflows/checks.yml)\n\nLightweight form builder for React that lets you dynamically render form fields from validation schemas, manage multi-step flows, and simplify validation handling.\n\n**[View Live Demo](https://wildhoney.github.io/Formikate/)**\n\n## Features\n\n- Dynamically render form fields using [`zod`](https://github.com/colinhacks/zod) validation schemas\n- Declarative multi-step forms via `useFields` configuration\n- Inactive fields are automatically reset to their default values\n- Steps without active fields are automatically skipped during navigation\n- Per-step validation \u0026mdash; only fields on the current step (or earlier) are validated on submit\n\n## Getting started\n\nBegin by defining your validation schema and field descriptors:\n\n```tsx\nimport * as z from 'zod';\n\nexport const schema = z.object({\n    name: z.string().min(1, 'Name is required'),\n    address: z.string().min(1, 'Address is required'),\n    guest: z.boolean(),\n});\n\nexport type Schema = z.infer\u003ctypeof schema\u003e;\n\nexport const fields = {\n    name: { step: 'personal' as const, validate: schema.shape.name, value: '' },\n    address: {\n        step: 'delivery' as const,\n        validate: schema.shape.address,\n        value: '',\n    },\n    guest: {\n        step: 'personal' as const,\n        validate: schema.shape.guest,\n        value: false,\n    },\n};\n```\n\nImport `useForm` \u0026ndash; it accepts all of the same [`useFormik` (`Formik`) arguments](https://formik.org/docs/api/useFormik) (except `validate`, `validationSchema`, and `initialValues` which are handled internally). Initial values are derived from each field's `value` property:\n\n```tsx\nimport { useForm, useFields, Position } from 'formikate';\nimport { fields } from './utils';\n\nconst form = useForm\u003cSchema\u003e({\n    fields,\n    validateOnBlur: false,\n    validateOnChange: false,\n    onSubmit(values) {\n        if (!form.status.progress.last)\n            return void form.status.navigate.to(Position.Next);\n        console.log('Submitting', values);\n    },\n});\n```\n\nYou can use `form` to access [all of the usual](https://formik.org/docs/api/formik#props-1) Formik properties such as `form.values` and `form.errors`.\n\n## Defining Steps and Fields\n\nUse `useFields` to declare the step structure and field configuration. The `step` property on each field is strongly typed \u0026mdash; it must match one of the identifiers in the `steps` array:\n\n```tsx\nuseFields(form, () =\u003e ({\n    steps: ['personal', 'delivery', 'review'],\n    fields: {\n        ...fields,\n        address: {\n            ...fields.address,\n            active: form.values.guest === false,\n        },\n    },\n}));\n```\n\n### Config Shape\n\n| Property | Type                             | Description                               |\n| -------- | -------------------------------- | ----------------------------------------- |\n| `steps`  | `(string \\| number \\| symbol)[]` | Ordered list of step identifiers          |\n| `fields` | `Record\u003cstring, FieldConfig\u003e`    | Map of field names to their configuration |\n\n### Field Config\n\n| Property   | Type                         | Description                                                                                                     |\n| ---------- | ---------------------------- | --------------------------------------------------------------------------------------------------------------- |\n| `step`     | `string \\| number \\| symbol` | Which step this field belongs to \u0026mdash; must match one of the identifiers in `steps`                           |\n| `validate` | `ZodType`                    | Zod schema used for validation                                                                                  |\n| `value`    | `unknown`                    | Default/reset value for the field \u0026mdash; also used as the initial value when passed to `useForm`               |\n| `active`   | `boolean?`                   | Whether the field is active (default `true`). Inactive fields are excluded from validation and reset to `value` |\n\n### Automatic Step Skipping\n\nSteps where all fields have `active: false` are automatically skipped during navigation:\n\n```tsx\nuseFields(form, () =\u003e ({\n    steps: ['personal', 'delivery', 'review'],\n    fields: {\n        ...fields,\n        address: {\n            ...fields.address,\n            active: form.values.guest === false,\n        },\n    },\n}));\n```\n\nWhen `guest` is `true`, the `address` field is inactive, so the delivery step is skipped.\n\n## Status\n\nAfter calling `useFields`, the computed state is available on `form.status`:\n\n```tsx\nform.status.empty; // boolean — true when no fields/steps are configured\nform.status.field; // Record\u003cstring, { exists(), required, optional }\u003e\nform.status.progress; // step progression state\nform.status.navigate; // navigation controls\n```\n\n### Field State\n\n```tsx\nform.status.field.name.exists(); // true if the field is active\nform.status.field.name.required; // true if the Zod schema rejects `undefined`\nform.status.field.name.optional; // inverse of required\n```\n\n### Progress\n\n```tsx\nform.status.progress.current; // identifier of the current step\nform.status.progress.position; // zero-based index within visible steps\nform.status.progress.total; // total number of visible steps\nform.status.progress.first; // whether on the first visible step\nform.status.progress.last; // whether on the last visible step\nform.status.progress.steps; // array of { id, index } for visible steps\nform.status.progress.step; // map of step id → { visible, current }\n```\n\n### Navigation\n\n```tsx\nimport { Position } from 'formikate';\n\nform.status.navigate.to(Position.Next); // go to next step\nform.status.navigate.to(Position.Previous); // go to previous step\nform.status.navigate.to(Position.First); // go to first step\nform.status.navigate.to(Position.Last); // go to last step\nform.status.navigate.to('review'); // go to a specific step by id\n\nform.status.navigate.exists(Position.Next); // true if a next step exists\nform.status.navigate.exists(Position.Previous); // true if a previous step exists\nform.status.navigate.exists('review'); // true if a specific step is reachable\n```\n\n## Rendering\n\nUse Formikate's `Form` component to provide the form to child components:\n\n```tsx\nimport { Form, Position } from 'formikate';\n\n\u003cForm value={form}\u003e\n    \u003cform onSubmit={form.handleSubmit}\u003e\n        {form.status.field.name.exists() \u0026\u0026 (\n            \u003cinput type=\"text\" {...form.getFieldProps('name')} /\u003e\n        )}\n\n        {form.status.field.address.exists() \u0026\u0026 (\n            \u003cinput type=\"text\" {...form.getFieldProps('address')} /\u003e\n        )}\n\n        \u003cbutton\n            type=\"button\"\n            disabled={!form.status.navigate.exists(Position.Previous)}\n            onClick={() =\u003e form.status.navigate.to(Position.Previous)}\n        \u003e\n            Back\n        \u003c/button\u003e\n\n        \u003cbutton type=\"submit\"\u003e\n            {form.status.progress.last ? 'Submit' : 'Next'}\n        \u003c/button\u003e\n    \u003c/form\u003e\n\u003c/Form\u003e;\n```\n\n### Accessing Form in Child Components\n\nUse the `useFormContext` hook in child components to access the form with properly typed `status`:\n\n```tsx\nimport { useFormContext } from 'formikate';\nimport type { Schema } from './types';\n\nfunction NameField() {\n    const form = useFormContext\u003cSchema\u003e();\n\n    if (!form.status.field.name.exists()) return null;\n\n    return \u003cinput type=\"text\" {...form.getFieldProps('name')} /\u003e;\n}\n```\n\n## Empty State\n\nWhen all fields are inactive, `form.status.empty` is `true`:\n\n```tsx\n{\n    form.status.empty ? (\n        \u003cp\u003eNo fields available\u003c/p\u003e\n    ) : (\n        \u003cform onSubmit={form.handleSubmit}\u003e{/* ... */}\u003c/form\u003e\n    );\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwildhoney%2Fformikate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwildhoney%2Fformikate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwildhoney%2Fformikate/lists"}