<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Cla</title>
    <description>The latest articles on DEV Community by Cla (@foxhound87).</description>
    <link>https://dev.to/foxhound87</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F36179%2Fbeffc76d-ce8f-4889-875f-00826392f3ec.jpg</url>
      <title>DEV Community: Cla</title>
      <link>https://dev.to/foxhound87</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/foxhound87"/>
    <language>en</language>
    <item>
      <title>The Agentic Skills of mobx-react-form: How AI Assistants Now Master React Forms</title>
      <dc:creator>Cla</dc:creator>
      <pubDate>Tue, 04 Aug 2026 12:34:00 +0000</pubDate>
      <link>https://dev.to/foxhound87/the-agentic-skills-of-mobx-react-form-how-ai-assistants-now-master-react-forms-58mo</link>
      <guid>https://dev.to/foxhound87/the-agentic-skills-of-mobx-react-form-how-ai-assistants-now-master-react-forms-58mo</guid>
      <description>&lt;p&gt;Form handling in React has always been a manual, repetitive, and error-prone affair. For years, &lt;code&gt;mobx-react-form&lt;/code&gt; has solved the runtime side of that problem — reactive form state, validation, bindings — with a clean, declarative API. But 2025 changed what "solving a problem" means: AI coding assistants now write large chunks of our forms for us. The quality of that generated code, however, depends entirely on the quality of the context the model is given.&lt;/p&gt;

&lt;p&gt;Enter &lt;strong&gt;agentic skills&lt;/strong&gt;: packaged, installable instruction sets that teach AI assistants the precise idioms, APIs, and patterns of a library before they write a single line of code. The &lt;code&gt;foxhound87/skills&lt;/code&gt; repository brings this to &lt;code&gt;mobx-react-form&lt;/code&gt; with a curated collection of 16 specialized skills — one for every major area of the library.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Are Agent Skills?
&lt;/h2&gt;

&lt;p&gt;Agent skills are essentially prompt-level documentation that lives on the agent's side. They contain the kind of knowledge a senior developer has internalized: exact method signatures, edge cases, the &lt;em&gt;right&lt;/em&gt; pattern versus the &lt;em&gt;working&lt;/em&gt; pattern. When an AI assistant is asked to build a multi-step form or wire up async validation, it doesn't have to guess — it loads the relevant skill and follows battle-tested guidance.&lt;/p&gt;

&lt;p&gt;Skills for &lt;code&gt;mobx-react-form&lt;/code&gt; are distributed via &lt;a href="https://skills.sh" rel="noopener noreferrer"&gt;skills.sh&lt;/a&gt; and can be installed in seconds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install the full collection&lt;/span&gt;
npx skills add https://github.com/foxhound87/skills &lt;span class="nt"&gt;--all&lt;/span&gt;

&lt;span class="c"&gt;# Install a single skill&lt;/span&gt;
npx skills add https://github.com/foxhound87/skills &lt;span class="nt"&gt;--skill&lt;/span&gt; mobx-react-form-validation

&lt;span class="c"&gt;# Install for a specific agent (e.g. opencode)&lt;/span&gt;
npx skills add https://github.com/foxhound87/skills &lt;span class="nt"&gt;-a&lt;/span&gt; opencode &lt;span class="nt"&gt;--all&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The Skill Collection: From Core to Advanced
&lt;/h2&gt;

&lt;p&gt;The 16 skills mirror the mental model of the library itself: a core API layer, a set of field-definition skills, validation, and then a cluster of advanced capabilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Core Skills
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Skill&lt;/th&gt;
&lt;th&gt;What it teaches the agent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mobx-react-form-api&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Installation, &lt;code&gt;Form&lt;/code&gt;/&lt;code&gt;Field&lt;/code&gt; constructor, full property and method reference, helpers, event handlers. The prerequisite for everything else.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mobx-react-form-flat&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Flat field definitions — unified, separated, and mixed modes, field properties, patterns.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mobx-react-form-nested&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Nested and array fields — dot notation, array notation, dynamic add/remove, &lt;code&gt;ArrayMap&lt;/code&gt;, field traversal.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mobx-react-form-validation&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;All six validation plugins (DVR, VJF, SVK, YUP, JOI, ZOD), async and cross-field validation, validation hooks.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mobx-react-form-bindings&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Field bindings — default rewriter/template, custom bindings, &lt;code&gt;$try&lt;/code&gt;, per-field mapping, UI framework adapters.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mobx-react-form-multi-step&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Multi-step wizard forms — nested groups, per-step validation, navigation, review screens.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Advanced Skills
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Skill&lt;/th&gt;
&lt;th&gt;What it teaches the agent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mobx-react-form-events&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Event hooks and handlers — &lt;code&gt;onInit&lt;/code&gt;, &lt;code&gt;onChange&lt;/code&gt;, &lt;code&gt;onFocus&lt;/code&gt;, &lt;code&gt;onBlur&lt;/code&gt;, &lt;code&gt;onSubmit&lt;/code&gt;, &lt;code&gt;onSuccess&lt;/code&gt;, &lt;code&gt;onError&lt;/code&gt;, key events.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mobx-react-form-observers-interceptors&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;MobX observers and interceptors — observing field changes, intercepting mutations, rejecting/modifying values, disposers.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mobx-react-form-computed&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Reactive computed props and &lt;code&gt;autorun&lt;/code&gt; — computed field values, autorun-derived totals, row calculations.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mobx-react-form-composer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The forms composer — orchestrating multiple &lt;code&gt;Form&lt;/code&gt; instances with batch validate/submit/clear/reset.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mobx-react-form-converters&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Input/output converters — transforming values between input and store, per-field and separated mode.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mobx-react-form-file-upload&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;File upload fields — &lt;code&gt;type: file&lt;/code&gt;, drag-and-drop zones, &lt;code&gt;onDrop&lt;/code&gt; hooks, &lt;code&gt;FileList&lt;/code&gt; access, validation.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mobx-react-form-sortable&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sortable arrays — &lt;code&gt;move()&lt;/code&gt;, &lt;code&gt;ArrayMap&lt;/code&gt; reordering, drag-and-drop with &lt;code&gt;@dnd-kit&lt;/code&gt;, up/down buttons.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mobx-react-form-extend&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Extending &lt;code&gt;Form&lt;/code&gt; and &lt;code&gt;Field&lt;/code&gt; classes — custom field classes, &lt;code&gt;makeField()&lt;/code&gt;, generic and specific extension.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mobx-react-form-options&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Form and field options — validation timing, error display, strict modes, debounce, data retrieval.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  What the Skills Actually Contain
&lt;/h2&gt;

&lt;p&gt;A skill isn't a vague prompt — it's structured, actionable reference material. The &lt;code&gt;mobx-react-form-validation&lt;/code&gt; skill, for example, documents all six validation drivers with ready-to-use setup snippets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ZOD — TypeScript-first schema validation&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;zodValidator&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mobx-react-form/lib/validators/ZOD&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zod&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;email&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;plugins&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;zod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;zodValidator&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;package&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But more importantly, it encodes the &lt;em&gt;non-obvious&lt;/em&gt; knowledge — the things that trip up both humans and AI models:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Async validation&lt;/strong&gt;: returning Promises from VJF validators, &lt;code&gt;registerAsync&lt;/code&gt; for DVR, async &lt;code&gt;onChange&lt;/code&gt; hooks that call &lt;code&gt;field.invalidate()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-field validation&lt;/strong&gt; via the &lt;code&gt;related&lt;/code&gt; property, so changing &lt;code&gt;password&lt;/code&gt; re-validates &lt;code&gt;passwordConfirm&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The full validation-options matrix&lt;/strong&gt;: &lt;code&gt;validateOnInit&lt;/code&gt;, &lt;code&gt;validateOnBlur&lt;/code&gt;, &lt;code&gt;showErrorsOnChange&lt;/code&gt;, &lt;code&gt;validationDebounceWait&lt;/code&gt;, &lt;code&gt;stopValidationOnError&lt;/code&gt;, and how per-field options override form-level ones.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plugin ordering&lt;/strong&gt; with &lt;code&gt;validationPluginsOrder&lt;/code&gt; when mixing drivers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Programmatic invalidation&lt;/strong&gt; with &lt;code&gt;field.invalidate(msg, deep, async)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last category is the real value of agentic skills: the difference between code that &lt;em&gt;works&lt;/em&gt; and code that's &lt;em&gt;idiomatic&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Matters for AI-Generated Code
&lt;/h2&gt;

&lt;p&gt;Anyone who has used an AI assistant to scaffold a form knows the failure modes: a model that trained on generic form libraries will happily generate &lt;code&gt;useState&lt;/code&gt;-based controlled inputs, invent non-existent methods, or skip the &lt;code&gt;onError&lt;/code&gt; hook entirely. The generated code compiles, renders, and &lt;em&gt;almost&lt;/em&gt; works — until you hit validation.&lt;/p&gt;

&lt;p&gt;Skills eliminate the guesswork. The &lt;code&gt;mobx-react-form-api&lt;/code&gt; skill alone encodes the entire architecture — &lt;code&gt;Form&lt;/code&gt; → &lt;code&gt;fields: ArrayMap&amp;lt;Field&amp;gt;&lt;/code&gt; → state/bindings/validator — plus the full method table, so a model asked to "add a reset button" reaches straight for &lt;code&gt;form.reset()&lt;/code&gt; instead of re-implementing state management.&lt;/p&gt;

&lt;p&gt;There's also a practical benefit beyond correctness: &lt;strong&gt;faster iteration&lt;/strong&gt;. Instead of prompting an agent with context and then debugging the result, the skill gives it the right primitives up front. Fewer rounds of "no, that's not how the API works."&lt;/p&gt;




&lt;h2&gt;
  
  
  The Library's Design Makes This Easy
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;mobx-react-form&lt;/code&gt; is unusually well-suited for agentic skills because of its consistency:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Everything is reactive&lt;/strong&gt; — form and field properties are MobX observables, and &lt;code&gt;observer()&lt;/code&gt;-wrapped components re-render automatically. Agents just need to know which properties are computed (&lt;code&gt;isValid&lt;/code&gt;, &lt;code&gt;isDirty&lt;/code&gt;, &lt;code&gt;isPristine&lt;/code&gt;, &lt;code&gt;hasError&lt;/code&gt;...) versus editable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One selector for everything&lt;/strong&gt; — &lt;code&gt;form.$('path')&lt;/code&gt; / &lt;code&gt;form.select()&lt;/code&gt; works for flat, nested, and array fields with the same dot-notation syntax.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Declarative validation&lt;/strong&gt; — rules live in field definitions, so agents can express complex logic as configuration instead of imperative code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uniform extension points&lt;/strong&gt; — &lt;code&gt;plugins()&lt;/code&gt;, &lt;code&gt;hooks()&lt;/code&gt;, &lt;code&gt;bindings()&lt;/code&gt;, and class extension via &lt;code&gt;makeField()&lt;/code&gt; cover almost every customization need.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When an API is this regular, a skill can document a small number of patterns that cover a very large space of use cases. That's precisely what makes the skill set effective.&lt;/p&gt;




&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install the skills&lt;/strong&gt; for your agent of choice (opencode, Claude Code, Cursor, and others are supported by skills.sh).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Start with the core trio&lt;/strong&gt;: &lt;code&gt;mobx-react-form-api&lt;/code&gt;, &lt;code&gt;mobx-react-form-nested&lt;/code&gt;, and &lt;code&gt;mobx-react-form-validation&lt;/code&gt; — they cover the 80% use case.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bring in the rest as needed&lt;/strong&gt;: reach for &lt;code&gt;multi-step&lt;/code&gt;, &lt;code&gt;sortable&lt;/code&gt;, or &lt;code&gt;file-upload&lt;/code&gt; when the requirement appears.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Let the agent load the skill&lt;/strong&gt; when prompting — e.g., "using the mobx-react-form-validation skill, add cross-field validation for the password fields."&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The repository is MIT-licensed and actively maintained by foxhound87 (the author of &lt;code&gt;mobx-react-form&lt;/code&gt; himself), so the skills track the library's actual behavior — not a stale approximation of it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Agent skills represent a shift in how we document libraries: from documentation &lt;em&gt;you&lt;/em&gt; read, to documentation &lt;em&gt;the AI&lt;/em&gt; reads — so the AI can write code as if it had read the docs itself. With 16 skills spanning the full API surface of &lt;code&gt;mobx-react-form&lt;/code&gt;, the &lt;code&gt;foxhound87/skills&lt;/code&gt; repository turns AI assistants into competent React form developers out of the box.&lt;/p&gt;

&lt;p&gt;The era of AI generating &lt;code&gt;useState&lt;/code&gt;-spaghetti for forms is over — at least for anyone willing to spend 30 seconds installing a skill.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Repository: &lt;a href="https://github.com/foxhound87/skills" rel="noopener noreferrer"&gt;github.com/foxhound87/skills&lt;/a&gt; · MIT License · Install via &lt;code&gt;npx skills add https://github.com/foxhound87/skills --all&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;📚 &lt;strong&gt;Documentation&lt;/strong&gt;: &lt;a href="https://foxhound87.github.io/mobx-react-form" rel="noopener noreferrer"&gt;mobx-react-form docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🚀 &lt;strong&gt;Live Demo&lt;/strong&gt;: &lt;a href="https://foxhound87.github.io/mobx-react-form-demo" rel="noopener noreferrer"&gt;mobx-react-form-demo&lt;/a&gt; · &lt;a href="https://github.com/foxhound87/mobx-react-form-demo" rel="noopener noreferrer"&gt;demo code&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Why mobx-react-form Is the Best Form Library You're Not Using</title>
      <dc:creator>Cla</dc:creator>
      <pubDate>Sat, 06 Jun 2026 20:00:00 +0000</pubDate>
      <link>https://dev.to/foxhound87/why-mobx-react-form-is-the-best-form-library-youre-not-using-16kd</link>
      <guid>https://dev.to/foxhound87/why-mobx-react-form-is-the-best-form-library-youre-not-using-16kd</guid>
      <description>&lt;p&gt;If you build forms in React, you've probably tried Formik, React Hook Form, or final-form. They're good. But if you deal with &lt;strong&gt;complex, deeply nested, multi-step forms&lt;/strong&gt; — the kind that make you question your life choices — there's a better tool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;mobx-react-form&lt;/strong&gt; combines MobX reactivity with a powerful form state engine. Here's why it deserves your attention.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Nested Fields Without the Pain
&lt;/h2&gt;

&lt;p&gt;Real forms aren't flat. Take an invoice: you have a customer section, a shipping address, and a variable number of products, each with name, quantity, and price.&lt;/p&gt;

&lt;p&gt;MRF handles this natively:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;customer.name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;customer.email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;shipping.address&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;shipping.city&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;shipping.zip&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;products&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;products[].name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;products[].quantity&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;products[].unitPrice&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each path becomes an observable field with its own validation, errors, and dirty tracking. No flattening. No normalization. The values serialize back to exactly the structure your API expects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"customer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"shipping"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"city"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"zip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"products"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Widget A"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"quantity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"unitPrice"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;19.99&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And with &lt;strong&gt;v6.15&lt;/strong&gt;, errors bubble up automatically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MobxReactForm&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;bubbleUpErrorMessages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// When products[0].product is empty, this just works:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ErrorBanner&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  2. Validation Plugins — Bring Your Own
&lt;/h2&gt;

&lt;p&gt;MRF doesn't lock you into one validator. It supports &lt;strong&gt;6 validation plugins&lt;/strong&gt; out of the box:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plugin&lt;/th&gt;
&lt;th&gt;Package&lt;/th&gt;
&lt;th&gt;Style&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;DVR&lt;/td&gt;
&lt;td&gt;validatorjs&lt;/td&gt;
&lt;td&gt;Declarative rules (`'required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VJF&lt;/td&gt;
&lt;td&gt;Custom functions&lt;/td&gt;
&lt;td&gt;{% raw %}&lt;code&gt;(value) =&amp;gt; [isValid, message]&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ZOD&lt;/td&gt;
&lt;td&gt;zod&lt;/td&gt;
&lt;td&gt;Schema-based&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;YUP&lt;/td&gt;
&lt;td&gt;yup&lt;/td&gt;
&lt;td&gt;Schema-based&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JOI&lt;/td&gt;
&lt;td&gt;joi&lt;/td&gt;
&lt;td&gt;Schema-based&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SVK&lt;/td&gt;
&lt;td&gt;ajv&lt;/td&gt;
&lt;td&gt;Schema-based&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Use DVR for simple fields and ZOD for complex cross-field validation — in the same form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;dvr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;dvr&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;package&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;validatorjs&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="na"&gt;zod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;zod&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;package&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;invoiceSchema&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Define a Zod schema for your entire form and get both client-side validation and TypeScript types from one source:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;invoiceSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;email&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;products&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;number&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;unitPrice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;number&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;positive&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="p"&gt;})).&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Full TypeScript Generics (v6.13)
&lt;/h2&gt;

&lt;p&gt;If you're on TypeScript, MRF now offers &lt;strong&gt;end-to-end type safety&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;InvoiceForm&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nl"&gt;shipping&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nl"&gt;products&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;unitPrice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;MobxReactForm&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;InvoiceForm&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;products[0]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Field&amp;lt;string&amp;gt; — fully typed&lt;/span&gt;
&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;                        &lt;span class="c1"&gt;// InvoiceForm — fully typed&lt;/span&gt;
&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;customer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Acme Corp&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// type-safe setter&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Plus &lt;strong&gt;&lt;code&gt;PathsOf&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/strong&gt; for autocomplete:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ship&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// → editor suggests: 'shipping.address' | 'shipping.city' | 'shipping.zip'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No more guessing field paths. No more runtime errors from typos.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Dynamic &amp;amp; Array Fields
&lt;/h2&gt;

&lt;p&gt;Need to add products dynamically? Remove a shipping address from a list? Built in.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Add a product&lt;/span&gt;
&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;products&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;product&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;New Product&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;unitPrice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Remove the second product&lt;/span&gt;
&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;products&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;del&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Reorder (new in v6.14 with ArrayMap)&lt;/span&gt;
&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;products&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Arrays, nested arrays, dynamic field creation — MRF handles all of it with MobX reactivity. Each item gets its own validation lifecycle, dirty tracking, and error state.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Composer — Multi-Form Orchestration
&lt;/h2&gt;

&lt;p&gt;Have independent forms that need to submit together? The &lt;code&gt;composer()&lt;/code&gt; function coordinates validation across forms:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;checkout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;composer&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;billing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;shipping&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payment&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;checkout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;submitOrder&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;billing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;shipping&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shipping&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// errors is keyed by form name: { billing: {...}, shipping: {...}, payment: {...} }&lt;/span&gt;
    &lt;span class="nf"&gt;showValidationSummary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perfect for checkout flows, multi-tab dashboards, and wizard-style UIs where each step is an independent form.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. UI Library Agnostic
&lt;/h2&gt;

&lt;p&gt;MRF works with every major UI library — and doesn't force you to pick one:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Material UI&lt;/li&gt;
&lt;li&gt;Ant Design&lt;/li&gt;
&lt;li&gt;React Aria&lt;/li&gt;
&lt;li&gt;Headless UI&lt;/li&gt;
&lt;li&gt;React Widgets&lt;/li&gt;
&lt;li&gt;React-Select&lt;/li&gt;
&lt;li&gt;Plain HTML&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each gets a thin binding layer. The form logic stays the same whether you render with MUI TextFields or raw &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; elements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Works the same regardless of UI library&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Input&lt;/span&gt; &lt;span class="na"&gt;field&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;customer.name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Input&lt;/span&gt; &lt;span class="na"&gt;field&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;customer.email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Save&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Swap the Input component from MaterialTextField to AntdInput to SimpleInput — the form state doesn't care.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Built for Production, Maintained for Years
&lt;/h2&gt;

&lt;p&gt;MRF has been powering production forms for &lt;strong&gt;8+ years&lt;/strong&gt;. It has &lt;strong&gt;1.1k+ GitHub stars&lt;/strong&gt;, and the latest releases (June 2026) brought the most requested features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;v6.15&lt;/strong&gt; — Error bubbling in nested forms&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;v6.14&lt;/strong&gt; — ArrayMap with predictable ordering and drag-and-drop support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;v6.13&lt;/strong&gt; — Full TypeScript generics, strict null checks, path autocomplete&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;v6.12&lt;/strong&gt; — Custom validation type inference, YUP &lt;code&gt;.ref()&lt;/code&gt; support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;v6.11&lt;/strong&gt; — Full null values support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each release was driven by real production needs, not hypothetical use cases.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;MRF&lt;/th&gt;
&lt;th&gt;Alternatives&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Simple login form&lt;/td&gt;
&lt;td&gt;✅ Overkill but works&lt;/td&gt;
&lt;td&gt;✅ Great fit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deeply nested fields (invoice, order, profile)&lt;/td&gt;
&lt;td&gt;✅ Native support&lt;/td&gt;
&lt;td&gt;❌ Requires flattening&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dynamic arrays (add/remove/reorder)&lt;/td&gt;
&lt;td&gt;✅ Built-in&lt;/td&gt;
&lt;td&gt;❌ Manual state mgmt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-form validation (checkout, wizard)&lt;/td&gt;
&lt;td&gt;✅ Composer&lt;/td&gt;
&lt;td&gt;❌ Custom orchestration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Validation plugins (DVR/ZOD/YUP/JOI)&lt;/td&gt;
&lt;td&gt;✅ 7 plugins&lt;/td&gt;
&lt;td&gt;❌ Usually 1-2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TypeScript generics + path autocomplete&lt;/td&gt;
&lt;td&gt;✅ v6.13+&lt;/td&gt;
&lt;td&gt;❌ Limited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Error bubbling in nested forms&lt;/td&gt;
&lt;td&gt;✅ v6.15+&lt;/td&gt;
&lt;td&gt;❌ Manual recursion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UI library flexibility&lt;/td&gt;
&lt;td&gt;✅ Any library&lt;/td&gt;
&lt;td&gt;✅ Any library&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you build forms beyond a login page — invoices, checkouts, multi-step registrations, admin panels with dynamic sections — give MRF a try. It handles the complexity so you don't have to.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save&lt;/span&gt; mobx-react-form
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;a href="https://foxhound87.github.io/mobx-react-form-demo" rel="noopener noreferrer"&gt;Try the live demo&lt;/a&gt;&lt;/strong&gt; | &lt;strong&gt;&lt;a href="https://github.com/foxhound87/mobx-react-form" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/strong&gt; | &lt;strong&gt;&lt;a href="https://foxhound87.github.io/mobx-react-form" rel="noopener noreferrer"&gt;Docs&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>mobx</category>
      <category>react</category>
      <category>form</category>
      <category>development</category>
    </item>
  </channel>
</rss>
