How to implement a custom CMS field type that integrates with the model builder's fluent API. Covers extending DataFieldBuilder, composing validator interfaces, creating a FieldTypeFactory, registering via DI, and module augmentation for TypeScript autocomplete on the fields() registry.
SkillScore100Maintained
Automatic
◆Coding pack
Last verified 8/12/2026
What it changes
Passed 22 of 22 test cases with the skill, and 6 of 22 without it.
Without skill27%
With skill100%
Checks it passed that the model alone missed
Implements FieldType.Factory
Implements ModelFactory.Interface
Calls help to set the field help text
and 23 more in the full report
16 fixed6 passed either way0 still failing0 broke
Pass-rate lift
+73 pp
Tokens
+58%
Agent turns
0%
Response time
-58%
Model gemini-3.6-flashMeasured 8/12/2026v122 of 22 cases passed with skill
Tokens, turns and time describe resource use, not a dollar price.
See it in action
One of 16 test cases the skill fixed. Same model, same prompt, with and without the skill.
1 of 16
Prompt
If a developer needs to explicitly set the field ID on a field builder rather than letting Webiny derive it from the property name, what method should be called?
What was checked, without and with the skill
Checked
Without skill
With skill
Calls the fieldId method on the builder
Missed
Passed
case-19 · gemini-3.6-flash · 8/12/2026 · answers are capped and redacted
What's inside
The instructions your model reads when the skill loads.
SKILL.md253 linessingle file
Custom CMS Field Type
TL;DR
A custom field type is a class that extends DataFieldBuilder<"yourType">, paired with a factory class implementing FieldType.Factory. Register the factory with container.register(YourFieldType). Add a module augmentation on "webiny/api/cms/model" so the fields registry method gets TypeScript autocomplete.
When to Use This
Use a custom field type when:
You need a field with a storage format or validation logic not covered by the built-in types (text, number, boolean, datetime, file, ref, object, richText, longText, json, dynamicZone)
You want to expose a fluent builder API (e.g., fields.slug(), fields.color()) in ModelFactory implementations
Field Type Structure
A custom field type consists of three parts:
Builder interface — extends DataFieldBuilder<"type"> plus FieldTypeValidator.* types
Builder class — implements the interface, calls this.validation() for each validator
Factory class — implements FieldType.Factory, creates builder instances
As a standalone extension (not part of a larger feature), the directory layout is:
extensions/
└── SlugFieldType/
├── SlugFieldType.ts # builder interface, builder class, factory class
└── feature.ts # createFeature — registers the factory into the DI container