{"id":17279215,"url":"https://github.com/mainej/f-form","last_synced_at":"2025-07-19T16:12:55.218Z","repository":{"id":49421996,"uuid":"283837861","full_name":"mainej/f-form","owner":"mainej","description":"Simple, immutable form management for Clojure(Script)","archived":false,"fork":false,"pushed_at":"2023-10-27T17:04:04.000Z","size":176,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-31T15:49:53.515Z","etag":null,"topics":["clojure","re-frame","reagent"],"latest_commit_sha":null,"homepage":"https://cljdoc.org/d/com.github.mainej/f-form","language":"Clojure","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/mainej.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","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}},"created_at":"2020-07-30T17:34:09.000Z","updated_at":"2023-02-10T06:39:33.000Z","dependencies_parsed_at":"2024-12-04T16:34:12.466Z","dependency_job_id":"b5e2b7ac-167c-4500-8a4e-79127dc67020","html_url":"https://github.com/mainej/f-form","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mainej%2Ff-form","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mainej%2Ff-form/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mainej%2Ff-form/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mainej%2Ff-form/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mainej","download_url":"https://codeload.github.com/mainej/f-form/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245672521,"owners_count":20653769,"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":["clojure","re-frame","reagent"],"created_at":"2024-10-15T09:16:30.741Z","updated_at":"2025-03-26T14:41:23.904Z","avatar_url":"https://github.com/mainej.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# f-form\n\nSimple immutable form management for Clojure(Script).\n\n## Installation\n\nInstall from Clojars:\n\n[![Clojars Project](https://img.shields.io/clojars/v/com.github.mainej/f-form.svg)](https://clojars.org/com.github.mainej/f-form)\n\nInstall unreleased sha from Github (assuming Clojure CLI 1.10.3.933 or higher):\n\n```clojure\n# deps.edn\n{:deps\n  {com.github.mainej/f-form {:git/sha \"\u003crecent sha\u003e\"}}}\n```\n\nUpdating? See the [CHANGELOG.md][changelog].\n\n## Background\n\n`f-form` aims to be a pared down functional Clojure version of [Final\nForm][final-form], a JS library for managing form state.\n\nThe primary goal of a form, on the web or in a CLI, is to collect data from a\nuser. But data entry is only part of the story. Many UIs need to remember and\nrespond to the various ways that a user might interact with a form. As a form\ndesigner, you may want to show a user which fields they have completed, are\ncurrently working on, or still have to finish. You may want to warn them about\ninvalid data, but only after they have interacted with an invalid field. You may\nwant to prevent form submission until all errors are resolved, until certain\ndata is entered or changed, or while a previous submission is in flight. There's\na lot to keep track of besides the values that the user has entered.\n\nAt the same time, there are only a few actions a user can take. They can start a\nform, switch between fields, enter data, and submit.\n\n`f-form` provides a minimal set of tools to define forms and their fields and\ntrack a user's interactions.\n\nBut most form libraries do this. What makes `f-form` unique is what it doesn't\ndo:\n\n* **No state management.** The `f-form` suite of tools accepts and returns\n  immutable forms that contain field values and a summarized history of a user's\n  interactions with them. But that's not enough... an app has to store those\n  forms and update them over time. `f-form` expects you to choose and use your\n  own state manager. The ClojureScript community has a rich set of options for\n  managing state. If you are using React, you may want to store state locally\n  with reagent, or in a re-frame app-db. If you are using `f-form` in another\n  context, the choice is up to you.\n* **No HTML or CSS.** `f-form` makes no decisions about how DOM elements are\n  generated or how to style them. Actually, it doesn't care whether you are\n  working in the DOM, in a CLI, or elsewhere. Instead, it provides the data you\n  need to make your own UI. It aims to do this efficiently by tracking only the\n  interactions you care about.\n* **No validation.** Though `f-form` expects that you will validate your forms,\n  it does not require validation or any particular validation library, nor does\n  it introduce its own validation syntax. Validation happens externally, not\n  internally. `f-form` provides a sample, optional, set of tools for client-side\n  validation with `vlad`, and contributions for other validation libraries are\n  welcome, but these will always be opt-in.\n* **No submission logic.** `f-form` helps you decide _whether_ to submit, but\n  not _how_ to submit. The tradeoff is that you have to inform `f-form` when you\n  are submitting.\n\n## Learn more\n\n* Run an example [reagent project that uses f-form][reagent-example].\n* See the [API Docs][docs].\n* Review the [code and tests][code].\n* Interested in contributing? Review the [contributing guidelines][contrib].\n\n## Alternatives\n\n- [`luciodale/fork`][fork] is another good option. It does a lot of state\n  management internally, which ties it to reagent or re-frame and hides some\n  useful functionality.\n- [`efraimmgon/reframe-forms`][reframe-forms], as the name suggests, is closely\n  tied to re-frame. It generates the HTML and does its own state management.\n- [`jkk/formative`][formative] is the maximal approach including validation,\n  rendering, even server-side parsing.\n\n## License\n\nCopyright © 2021 Jacob Maine\n\nDistributed under the MIT License.\n\n[code]: https://github.com/mainej/f-form\n[docs]: https://cljdoc.org/d/com.github.mainej/f-form\n[contrib]: https://github.com/mainej/f-form/blob/main/CONTRIBUTING.md\n[changelog]: https://github.com/mainej/f-form/blob/main/CHANGELOG.md\n[reagent-example]: https://github.com/mainej/f-form/tree/main/examples/reagent\n\n[final-form]: https://final-form.org/\n[fork]: https://github.com/luciodale/fork\n[reframe-forms]: https://github.com/efraimmgon/reframe-forms\n[formative]: https://github.com/jkk/formative\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmainej%2Ff-form","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmainej%2Ff-form","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmainej%2Ff-form/lists"}