{"id":20631202,"url":"https://github.com/nedpals/formuler","last_synced_at":"2025-07-20T17:32:41.116Z","repository":{"id":261517644,"uuid":"884394786","full_name":"nedpals/formuler","owner":"nedpals","description":"A form renderer built for React. Create scalable, complex forms at less effort with the power of JSON Schema.","archived":false,"fork":false,"pushed_at":"2024-11-25T15:49:48.000Z","size":148,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-09T11:17:07.179Z","etag":null,"topics":["form","form-rendering","json-schema","react"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nedpals.png","metadata":{"files":{"readme":".github/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}},"created_at":"2024-11-06T17:09:44.000Z","updated_at":"2024-11-25T15:51:09.000Z","dependencies_parsed_at":"2025-07-20T17:32:16.964Z","dependency_job_id":null,"html_url":"https://github.com/nedpals/formuler","commit_stats":null,"previous_names":["nedpals/formuler"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/nedpals/formuler","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nedpals%2Fformuler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nedpals%2Fformuler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nedpals%2Fformuler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nedpals%2Fformuler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nedpals","download_url":"https://codeload.github.com/nedpals/formuler/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nedpals%2Fformuler/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266165577,"owners_count":23886640,"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","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-rendering","json-schema","react"],"created_at":"2024-11-16T14:11:32.317Z","updated_at":"2025-07-20T17:32:41.083Z","avatar_url":"https://github.com/nedpals.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Formuler 📝\n\nA form renderer built for React. Create scalable, complex forms at less effort with the power of JSON Schema.\n\n## Features\n- **Dynamic Form Rendering**: It uses JSON schema to define and render forms. Fetch the schema from the server or define it locally.\n- **Great Customizability**: Customize Form behavior with JSON Schema Form, style our default UI components, or use your favorite UI libraries directly.\n- **Compatible with Existing Libraries**: Use it with your favorite form libraries like Formik, react-hook-form, or react-jsonschema-form.\n- **Type-Safe**: Build type-safe forms easily with TypeScript. (WIP)\n\n## Perfect for...\n- Simple forms\n- Complex, multi-layout forms\n- Multi-step / wizard forms\n- Remote web forms\n\n## Installation\n```bash\nnpm install formuler\n```\n\n## Quickstart\n```jsx\nimport React from 'react';\nimport { FormRenderer } from 'formuler';\nimport { SimpleForm, SimpleFormRenderer } from 'formuler/simple_form';\n\nexport default function App() {\n  // 1. Define your form's schema or fetch it remotely\n  const schema = {\n    type: 'object',\n    properties: {\n      name: {\n        type: 'string',\n        title: 'Name',\n        formProperties: {\n          type: 'input',\n          inputType: 'text',\n          placeholder: 'Enter your name',\n        }\n      },\n      age: {\n        type: 'number',\n        title: 'Age',\n        formProperties: {\n          type: 'input',\n          inputType: 'number',\n          placeholder: 'Enter your age',\n        }\n      },\n    },\n  };\n\n  // 2. Provide a value and a function to update the value.\n  // In this case, we will use `useState` and `SimpleForm` from `simple_form` subpackage\n  // (you can use your own form/state management library!)\n  const [value, setValue] = React.useState({\n    name: 'Bob',\n    age: 18,\n  });\n\n  // 3. Render your form using FormRenderer\n  return (\n    \u003cSimpleForm value={value} onChange={setValue}\u003e\n      \u003cFormRenderer\n        schema={schema}\n        render={SimpleFormRenderer} /\u003e\n    \u003c/SimpleForm\u003e\n  );\n}\n```\n\n## Usage\n### Extend/Override Default Components\nFormuler's built-in `simple_form` package provides default components for rendering forms.\nYou can extend or override them to fit your needs by overriding the simple_form's `SimpleFormRenderer` component.\nYou may override at various levels: schema type-level, form type level, property-level, and layout-level.\n\n```jsx\n\u003cFormRenderer\n  schema={schema}\n  render={(props) =\u003e (\n    \u003cSimpleFormRenderer\n      {...props}\n      byType={{\n        string: ({ formProperties }) =\u003e \u003cp className=\"text-xl\"\u003e{formProperties.content}\u003c/p\u003e,\n      }}\n      byFormType={{\n        input: (props) =\u003e (\n          \u003cdiv\u003e\n            \u003cp style={{ marginBottom: 0 }}\u003e\n              {props.formProperties.label}\n            \u003c/p\u003e\n            \u003cInput {...props} /\u003e\n          \u003c/div\u003e\n        ),\n      }} /\u003e\n  )} /\u003e\n```\n\n### Using Third Party Components and Form/State Management\nWhile Formuler provides its own built-in set of components for rendering forms, you may use your own as well directly\nwithout the need for a separate \"adapter\" package. Simply replace the render function with your favorite UI library components.\n\nThe same goes as well with form/state management libraries. Formuler does not provide an opinionated way of updating and setting\nform values and they are delegated instead to form libraries such as Formik and react-hook-form. You can use them inside your\ncustom components or in conjunction with `SimpleForm` component (when using the default components).\n\n### ShadCN + react-hook-forms example\n```jsx\nfunction default App() {\n  // ...\n\n  return (\n    \u003cForm {...form}\u003e\n      \u003cFormRenderer\n        schema={schema}\n        value={value}\n        onChange={setValue}\n        render={({ fullProperty }) =\u003e (\n          \u003cFormField\n            control={form.control}\n            name={fullProperty}\n            render={({ field }) =\u003e (\n              \u003cFormItem\u003e\n                \u003cFormLabel\u003eTest\u003c/FormLabel\u003e\n                \u003cFormControl\u003e\n                  \u003cOutlet {...field} /\u003e\n                \u003c/FormControl\u003e\n                \u003cFormMessage /\u003e\n              \u003c/FormItem\u003e\n            )} /\u003e\n        )}\n      /\u003e\n    \u003c/Form\u003e\n  );\n}\n```\n\n### Wizard Form through the `section` prop\n\nYou can extract or render only a section of your form's schema through the `section` prop.\nThis is perfect when you are building multi-step or wizard-like forms.\n\nIn this example, we have two sections: `personal_information` and `contact_information`.\n\n```jsonc\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"personal_information\": {\n      \"type\": \"object\",\n      \"formProperties\": {\n        \"type\": \"section\",\n        \"title\": {\n          \"type\": \"text\",\n          \"content\": \"Personal Information\"\n        },\n        \"description\": {\n          \"type\": \"text\",\n          \"content\": \"Please fill out the form below.\"\n        },\n      },\n      \"properties\": {\n        // ...\n      }\n    },\n    \"contact_information\": {\n      \"type\": \"object\",\n      \"formProperties\": {\n        \"type\": \"section\",\n        \"title\": {\n          \"type\": \"text\",\n          \"content\": \"Contact Information\"\n        },\n        \"description\": {\n          \"type\": \"text\",\n          \"content\": \"Please fill out the form below.\"\n        },\n      },\n      \"properties\": {\n        // ...\n      }\n    }\n  }\n}\n```\n\nWe want to have a two-step form with each step rendering a section. We can achieve this by passing\nthe `section` prop to the `FormRenderer` component.\n\n```jsx\n// Step 1 page\n\u003cFormRenderer\n  schema={schema}\n  value={value}\n  onChange={setValue}\n  section=\"personal_information\" /\u003e\n\n// Step 2 page\n\u003cFormRenderer\n  schema={schema}\n  value={value}\n  onChange={setValue}\n  section=\"contact_information\" /\u003e\n```\n\n## JSON Schema Form (JSF)\n\nFormuler provides a superset of JSON Schema that allows you to define form behavior\nwithin the schema itself, making it both flexible and erasable for validation purposes.\n\n### Elements\n\nJSF consists is composed of three main element types: **sections**, **layouts**, **contents**, and **controls**.\n\n- **Sections** allow you to segment and group part of your form with its own layout, title, and descriptions.\n- **Layouts** allow you to define custom layout for a specific part of the form (eg. grids, rows, columns)\n- **Contents** displays property values as static, non-editable elements (eg. images, videos, and etc.)\n- **Controls** ables to you to edit and control the schema's property value.\n\n#### List of Components\n- `section` - A section element that groups properties together.\n- `layout` - A layout element that defines the layout of the form.\n- `custom` - A custom element.\n- `content` - A content element that displays non-editable content.\n  - `text` - A text content element.\n  - `rich-text` - A rich text content element.\n  - `image` - An image content element.\n  - `video` - A video content element.\n  - `oembed` - An oembed content element.\n- `controls` - A controls element that defines the form controls.\n  - `button` - A button control element.\n  - `input` - An input control element.\n  - `custom-control` - A custom control element.\n\nFor full documentation, see [types/json_schema_form.ts](lib/types/json_schema_form.ts).\n\n### Example\nTo define the form properties for that specific property/schema, simply add a `formProperties`\n`object` property with `type` and its associated configurations.\n\n```json\n{\n  \"type\": \"object\",\n  \"formProperties\": {\n    \"type\": \"section\",\n    \"title\": {\n      \"type\": \"text\",\n      \"content\": \"Personal Information\"\n    },\n    \"description\": {\n      \"type\": \"text\",\n      \"content\": \"Please fill out the form below.\"\n    },\n  },\n  \"properties\": {\n    \"name\": {\n      \"type\": \"string\",\n      \"title\": \"Name\",\n      \"formProperties\": {\n        \"type\": \"input\",\n        \"inputType\": \"text\",\n        \"placeholder\": \"Enter your name\"\n      }\n    },\n    \"age\": {\n      \"type\": \"number\",\n      \"title\": \"Age\",\n      \"formProperties\": {\n        \"type\": \"input\",\n        \"inputType\": \"number\",\n        \"placeholder\": \"Enter your age\"\n      }\n    }\n  }\n}\n```\n\n## Goals\nThe current goals of Formuler are:\n- To be easy and flexible to use.\n- To be scalable and customizable.\n- To be usable in real-world applications.\n- To be compatible with existing form and UI libraries.\n\n...and eventually:\n- To be compliant with JSON Schema\n- To be fully type-safe\n- To be fully tested\n\n...and won't be:\n- A full-fledged form library\n- A replacement for existing form libraries\n\nThe goals are subject to change as the project progresses and\nbased on the needs I will encounter. Feel free to suggest any\nfeatures or improvements by [opening an issue](https://github.com/nedpals/formuler/issues).\n\n## Name Inspiration\n[Mr Krabs.](https://youtu.be/bVbvki7IvQY)\n\n## License\nLicensed under the [MIT License](LICENSE).\n\n## Copyright\n(c) 2024 Ned Palacios\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnedpals%2Fformuler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnedpals%2Fformuler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnedpals%2Fformuler/lists"}