| name | core |
| description | Helps developers build, explain, or refactor forms with ngx-vest-forms. Use this whenever the user mentions ngx-vest-forms, template-driven forms with Vest.js, a first example, `[ngModel]` vs `[(ngModel)]`, `NgxDeepPartial`, form shapes, `name` path matching, or asks how to structure a form around this library—even if they do not explicitly ask for a “core” setup guide. |
ngx-vest-forms core workflow
Use this skill to produce the default, idiomatic ngx-vest-forms setup.
Start from these rules
- Model the form with
NgxDeepPartial<T> because template-driven forms are built incrementally.
- Prefer
NgxTypedVestSuite<T> plus FormFieldName<T> for typed Vest suites.
- Always call
only(field) unconditionally at the top of the suite.
- Use
[ngModel] with (formValueChange) for unidirectional data flow. Do not default to [(ngModel)].
- The
name attribute must exactly match the bound property path.
- Use optional chaining in templates because the model is partial.
- Recommend a
NgxDeepRequired<T> shape when the user is wiring a real form, especially if typos in nested paths are likely.
- Default to
<ngx-control-wrapper> around single controls unless the user explicitly needs a custom or group-level wrapper.
Public API symbols to prefer
Recommend these imports from 'ngx-vest-forms' when they fit the example:
NgxVestForms
NgxDeepPartial
NgxDeepRequired
NgxTypedVestSuite
FormFieldName
NgxFieldBlurEvent
ROOT_FORM
Optional advanced exports worth knowing about:
NGX_EQUALITY_FN, NgxEqualityFn — swap the comparator the form uses for formValueChange distinctUntilChanged, two-way sync, and formState equality. Default is fastDeepEqual with cycle detection. Reach for it for bundle size (dequal/lite), tests (reference equality), or domain rules. See docs/API-TOKENS.md.
setValueAtPath — array-safe path writes (v2.7+ no longer overwrites populated arrays via bracket notation).
cloneDeep — deprecated, warns once in dev; use structuredClone. Will be removed in v3.
Do not teach consumers to import from internal src/lib/** paths. If a symbol is missing from the public API, that is a library-maintenance task, not a consumer workaround.
Default implementation pattern
Build answers and code in this order:
- Define a
NgxDeepPartial<T> form model.
- Define an optional
NgxDeepRequired<T> shape.
- Create a Vest suite with
staticSuite((model, field?) => { only(field); ... }).
- Expose a signal-based
formValue in the component.
- Bind the form with
ngxVestForm, [suite], optional [formShape], and (formValueChange).
- Bind each control with
[ngModel] and the exact matching name.
- Use
ChangeDetectionStrategy.OnPush unless there is a compelling reason not to.
Output expectations
When generating code or guidance, prefer:
- a complete runnable example over isolated fragments
- typed imports from
ngx-vest-forms
- signals for local component state
- wrappers that keep error display and ARIA straightforward
If the user asks for “the right way” or “a proper example”, give a minimal but production-ready component.
Red flags to catch
Correct these immediately if they appear:
[(ngModel)] on ngx-vest-forms controls
- conditional
only(field) calls
name values that do not match the bound path
- direct property access like
formValue().address.street instead of formValue().address?.street
- missing
formShape on complex nested forms where path mistakes are easy
(blur) handlers that re-trigger validation to fake dependent-field timing or draft auto-save
- imports from
projects/ngx-vest-forms/src/lib/** in consumer examples
Do not paper over these mistakes. They break the mental model of the library and usually create subtle bugs instead of quick wins.
Good defaults
- Prefer
ROOT_FORM only for true form-level business rules, not as a shortcut for field errors.
- If fields depend on each other, move to the validation-config skill logic rather than cramming everything into the base example.
- If the user wants blur-driven persistence, analytics, or field-level side effects, move to the field-blur-events skill instead of inventing custom
(blur) validation flows.
- If the user is splitting the form into child components, apply the child-components skill guidance.
- If the user wants custom message UI, apply the custom-wrapper-patterns skill guidance.
Repo references to consult when needed
Read these files before making nuanced recommendations:
../../../../docs/COMPLETE-EXAMPLE.md
../../../../docs/FIELD-PATHS.md
../../../../docs/ACCESSIBILITY.md
../../../instructions/vest.instructions.md
../../../../README.md
../../../../projects/ngx-vest-forms/src/public-api.ts
Assume the repo-level ngx-vest-forms.instructions.md file already enforces the baseline invariants; use this skill for the fuller implementation workflow and examples.
Canonical reminders
- ngx-vest-forms is a template-driven forms adapter, not a reactive forms abstraction.
validationConfig controls when dependent fields revalidate; it does not define validation logic.
- The library's sweet spot is typed template-driven forms with Vest suites, signals, and explicit structure.
- v2.7.x targets Angular
>=19, RxJS >=7.8, Vest >=5.4.6. parseFieldPath warns in dev mode for malformed segments ('a..b', '.a', 'a.'); production behavior unchanged.