Signal Forms: form(), FieldTree, and Schema Validation In short: Signal Forms turns the old design around. Your data becomes the truth, and the form is built from it. That one change removes all four problems from the last lesson. The whole idea in one example Your data is the truth. builds a view of it. There is no second shape, so there is nothing to keep in step — and every type in the form comes from your data automatically. The field tree gives you a tree that mirrors your data's shape. Move through it with dots, and it is fully typed: Call any part of it to get its state — the signals for that field: Every one is a signal, so templates read them directly: Note the three levels , because this is the main early stumble: is the field is its state is its value The directive One directive replaces , , and : It connects the value, input events, touched-on-blur, and the disabled state. Crucially it is a typed expression, not text. Rename a property in your data and the template fails to build . That alone removes a whole group of renaming bugs. CSS classes work as you would expect, and can be set app-wide: Validation Built-in validators take a path and any settings: Your own validators Checking two fields against each other This is where the new design earns its place. reads another field — and because that is a signal read, the validator re-runs automatically when that field changes : No . No subscription. And the error attaches to — the field that is actually wrong — instead of a parent you then have to reach up to in the template. That is Problem 3 from the last lesson, gone. Checking with the server Returning nothing from means no request — the same "do not fetch yet" idea as . is true while it runs, and replaced requests are handled for you. Pair it with so you are not checking on every keystroke: Conditional state , , and take conditions rather than being set by hand: v22 lets return a reason instead of just true, which is genuinely useful: Schemas — reusable rules A is a named, reusable set of rules for a shape: applies a schema to every item in a list, and applies one only sometimes: This is what Reactive Forms never had a clean answer for. An address checked the same way in three places is written once and used three times, with types checked each time. Lists Lists are just lists in your data, so you handle them as plain data: No . No / . No . The form follows the data because it is built from it. Problem 4, gone. Submitting handles the whole routine — marking fields touched, stopping if invalid, tracking , and putting server errors back on the right fields: Returning field-and-error pairs is the part worth noticing. Server validation failures land on the right fields with no manual work — the case every Reactive Forms project solved slightly differently. Your own form fields No . Just a plus some optional inputs: Compare that with the four-method interface plus a special registration. "But doesn't this mean Reactive Forms is dead?" It is not going away and still gets fixes. Angular has shipped two form systems side by side for a decade. There are now three, and that is fine. What is actually true: Signal Forms is the better tool for new work. That is the whole claim. Migrating a working form because it is "old" is how you spend a sprint bringing back bugs someone already fixed. Forms are unusually full of accumulated correctness — a validator that looks strange is usually strange because of a real bug report. The second question — "is this template-driven forms again?" The binding does look like . The resemblance is misleading: Template-driven Reactive Signal Forms --- --- --- --- Structure lives in Template Class Class The truth is Your data, unofficially The Your data, officially Validation lives in Template attributes Class validators Class schema Testable without drawing No Yes Yes Type safety None Partial Full, from your data The third — "won't signals in forms redraw constantly?" The opposite. Editing the email field marks only the parts reading . A 40-field Reactive Form with typically re-ran work for the whole form on every keystroke. The architect's view A checkout form is a good test case, because it needs everything at once: two addresses, a "same as billing" toggle, a discount code checked against the server, and a card section that only appears for card payments. Four failure modes that recur in Reactive Forms implementations of this , and they share a cause worth naming: 1. Toggling "same as billing" disables the shipping fields, but their old values remain in — so a stale address can reach the server. 2. Switching payment method means swapping the card validators, and any path that misses leaves an invalid card number passing validation. 3. The discount check races. Type quickly and a reply for an earlier code can arrive after a later one. 4. Server errors such as "email already registered" end up in a banner rather than on the field, because mapping them back is awkward. Every one i…