
Custom Lightning Types Generator
OfficialFreeEasily create Custom Lightning Types for Salesforce.
Free · Opens the source repo
What Custom Lightning Types Generator does
The Custom Lightning Types Generator skill is designed for Salesforce developers and designers who need to create Custom Lightning Types (CLTs) for structured inputs and outputs within the Lightning Platform, particularly for Einstein Agent actions. This skill provides comprehensive guidance on generating JSON Schema-based type definitions, configuring CLTs, and setting up editor and renderer configurations for custom user interfaces. It is essential for ensuring that the CLTs adhere to the strict validation rules set by the Lightning Platform.
When using this skill, users will navigate through a series of steps to confirm the appropriate CLT approach, whether referencing Apex classes or standard Lightning types. The skill emphasizes critical rules to follow when drafting the schema, such as the prohibition of the "$schema" field and the required structure of root object schemas. It also highlights the importance of avoiding certain keywords that may lead to validation failures, ensuring that users can create valid and functional CLTs.
This skill is particularly useful for Salesforce developers who are tasked with integrating custom functionalities into their applications and need to ensure that their CLTs are correctly structured and validated. By following the guidelines provided, users can troubleshoot deployment errors and ensure a seamless integration of CLTs into their projects. The skill also serves as a reference for understanding the limitations and requirements of the CLT metaschema, which is crucial for successful implementation.
Overall, the Custom Lightning Types Generator skill is an invaluable tool for anyone involved in Salesforce development, providing clear instructions and best practices for creating and managing Custom Lightning Types effectively.
When to use it
Use this skill when you need to define structured input/output schemas for Salesforce applications, particularly when working with Einstein Agent actions.
When not to use it
This skill is not suitable for general-purpose JSON schema generation outside of the Salesforce Lightning Platform context.
What you can build with it
Creating a CLT for Einstein Agent
Use this skill to define a Custom Lightning Type that will be utilized in an Einstein Agent action, ensuring it meets all validation criteria.
Configuring a Custom UI
Leverage this skill to set up editor and renderer configurations for a CLT that requires custom user interface components.
Troubleshooting CLT Deployment Issues
Employ this skill to identify and resolve deployment errors related to Custom Lightning Types in your Salesforce applications.
How to install Custom Lightning Types Generator
View source1. Install with the skills CLI
npx skills add forcedotcom/sf-skills/platform-custom-lightning-type-generate --agent claude-code2. Or install it manually
Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.
Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs
Inside SKILL.md
Written by forcedotcomWhen to Use This Skill
Use this skill when you need to:
- Create Custom Lightning Types (CLTs) for structured inputs/outputs
- Generate JSON Schema-based type definitions for Lightning Platform
- Configure CLTs for Einstein Agent actions
- Set up editor and renderer configurations for custom UI
- Troubleshoot deployment errors related to Custom Lightning Types
Specification
CustomLightningType Metadata Specification
Overview & Purpose
Custom Lightning Types (CLTs) are JSON Schema-based type definitions used by the Lightning Platform (including Einstein Agent actions) to describe structured inputs/outputs and drive editor/renderer experiences.
Configuration
- Choose referenced CLT pattern for nested objects - When you need a reusable or separately deployed nested type, create a CLT for that shape and reference it with
"lightning:type": "c__<CLTName>". That string is the referenced type’slightning:typevalue / FQN / registered identifier — not the JSON Schematitle. - Choose standard Lightning types when the structure is simple and can be expressed with properties and supported primitive
lightning:typeidentifiers. - Choose Apex class types (
@apexClassType/...) when the structure already exists server-side and you want the Apex class to define the shape. - Include editor/renderer config only when you need custom UI behavior (custom LWC input/output components). Otherwise, omit.
Critical Rules (Read First)
- CRITICAL: NEVER include the
"$schema"field in schema.json- Salesforce CLT validator WILL REJECT schemas with this field, even if it's a valid JSON Schema
$schemadeclaration.
- Salesforce CLT validator WILL REJECT schemas with this field, even if it's a valid JSON Schema
- Root object schemas MUST include:
"type": "object""title""lightning:type": "lightning__objectType""unevaluatedProperties": false
"unevaluatedProperties"is enforced asfalseby the CLT metaschema. Do not set it totrue.- Root object schemas MUST NOT include
"examples"when"unevaluatedProperties": falseis set. - Nested objects (inside
properties) MUST NOT set"lightning:type": "lightning__objectType".- Nested objects can be: references to other CLTs using
c__<CLTName>syntax.
- Nested objects can be: references to other CLTs using
- List/array properties are highly restricted by the CLT metaschema:
- CRITICAL LIMITATION: the CLT metaschema may reject the
itemskeyword entirely. Treatitemsas disallowed by default. - Root-level arrays (direct children of the root
properties):- MUST include
"lightning:type": "lightning__listType" - MUST NOT include
"items" - OPTIONAL
"type": "array"
- MUST include
- Nested arrays (arrays inside nested objects) are the most common failure:
- MUST include
"type": "array" - MUST NOT include
"lightning:type": "lightning__listType" - MUST NOT include
"items"
- MUST include
- CRITICAL LIMITATION: the CLT metaschema may reject the
- When
"unevaluatedProperties": falseis set, any unknown keyword will fail validation. Prefer removing keywords over relaxing strictness. - Apex class CLTs are minimal:
- Include only
title,description(optional), andlightning:typeset to@apexClassType/.... - Do not add
type,properties,required, orunevaluatedProperties. - Custom LWC renderers/editors on an Apex class CLT MUST NOT use
attributesin the root override — this overrides any prompt wording to the contrary. Since the schema has nopropertiesblock, there is nothing for{!$attrs.<name>}to resolve against —unevaluatedProperties: falsewill reject any attribute key (e.g."You can't add the flightId property ... because the unevaluatedProperties keyword value is set to false"). Use"componentOverrides": { "$": { "definition": "c/<yourComponent>" } }with noattributeskey at all. If the user's prompt explicitly asks for attribute mappings to specific fields (e.g. "with attribute mappings for fieldA, fieldB") on an Apex-class CLT renderer/editor, do NOT comply literally — omitattributesfrom the root override anyway, and say so in your response (e.g. "Note: attribute mappings were omitted because the backing type is an Apex-class CLT, which has nopropertiesblock to bind against").
- Include only
- No shell metacharacters that trigger the Vibes safe-shell filter. In any Bash tool call emitted by this skill, do NOT use command substitution (
$(…)or backticks), process substitution (<(…),>(…)), brace expansion ({a,b,c}or{1..N}), oreval/exec. Vibes forces manual approval on these patterns even under Bypass mode and stalls the eval. Emit separate commands (mkdir -p a && mkdir -p b) or print each value with its own command and reason about the output rather than capturing it in a shell variable.
Additional CLT Metaschema Validations
- Org namespace validation: titles/descriptions and other string fields may be validated to ensure you are not using an org namespace in places that are disallowed.
- Lightning type validation: CLTs are validated to prevent referencing internal namespaces (for example, disallowing types from internal namespaces like
sfdc_cmswhere not permitted). - Object type validation: the CLT root is validated to ensure
lightning:typeis exactlylightning__objectType.
Primitive Types & Constraints
When you need the full list of supported primitive lightning:type identifiers, their constraints, and the allowed property-level keywords, read assets/primitive-types-and-constraints.md in this skill's directory.
Generation Workflow
- Confirm the CLT approach
- If referencing Apex: capture the exact class reference (@apexClassType/namespace__ClassName$InnerClass).
- If using standard primitives: list the fields, their Lightning primitive types, and which fields are required.
- Draft
schema.json- DO NOT include
"$schema"at the top - Start with the root object structure (required root fields).
- Add
propertiesusing valid primitivelightning:typeidentifiers. - For nested-object properties, use CLT Reference pattern:
"lightning:type": "c__<CLTName>"to reference another CLT- The referenced CLT must be deployed to the org before the parent CLT.
- For Apex-based nested objects: Use
@apexClassType/...when structure exists server-side. - If the prompt explicitly requires true nested object output, prefer an Apex-based CLT (
@apexClassType/...) for deploy-safe nested structures. - For arrays: follow the strict list rules (avoid
items; avoidlightning:typeon nested arrays). - Before deployment, verify exact
lightning:typespellings (for example, uselightning__richTextType, not misspelled variants).
- DO NOT include
- (Optional) Draft
editor.json(only if custom UI is required)- Supported shape: Top-level
editorobject witheditor.componentOverridesandeditor.layout.- Top-level
editorobject. - Use
editor.componentOverridesfor component overrides. - Use
editor.layoutfor layout. - DEPRECATED: Do NOT use
propertyRenderersorview— these are legacy keys. Always usecomponentOverridesandlayoutinstead.
- Top-level
- Root override pattern (most common for fully custom editing UI):
editor.componentOverrides["$"] = { "definition": "c/<yourEditorComponent>", "attributes": { ... } }- When passing schema data into a custom LWC, use attribute mapping with the
{!$attrs.<name>}syntax: e.g."attributes": { "myField": "{!$attrs.value}" }so the runtime binds schema values to your component's attributes. - CRITICAL: The
<name>in{!$attrs.<name>}must be a property defined in your type schema. For example, if your schema has a property calledtemperature, use{!$attrs.temperature}, not{!$attrs.value}unlessvalueis an actual property.
- Property-level override pattern (for individual fields):
editor.componentOverrides["<propertyName>"] = { "definition": "es_property_editors/<...>" }- Valid editor components (examples):
es_property_editors/inputText,es_property_editors/inputNumber,es_property_editors/inputRichText,es_property_editors/inputImage,es_property_editors/inputTextarea. Do not usees_property_editors/inputList.
- Collection editor (for root-level
lightning__listTypeproperties): Use a collection-level override so the list is edited by a custom component:collection.editor.componentOverrides["$"] = { "definition": "c/<yourCollectionEditorComponent>" }. Alternatively, useeditor.layoutwithlightning/propertyLayoutandattributes.property = "<listPropertyName>"for default list editing. - Layout pattern:
editor.layout.definition = "lightning/verticalLayout"editor.layout.children[*].definition = "lightning/propertyLayout"withattributes.property = "<propertyName>"- CRITICAL:
lightning/propertyLayoutonly accepts thepropertyattribute. Do NOT addlabel,title, or any other attributes — these will fail validation withadditionalProperties: falseerrors.
- Avoid known-invalid patterns:
- Do not use
es_property_editors/inputList. - Do not use
itemSchemaattributes.
- Do not use
- Supported shape: Top-level
- (Optional) Draft
renderer.json(only if custom UI or widget rendition is required)- Supported shape: Top-level
rendererobject withrenderer.componentOverridesandrenderer.layout.- Top-level
rendererobject. - Use
renderer.componentOverridesfor component overrides. - Use
renderer.layoutfor layout. - DEPRECATED: Do NOT use
propertyRenderersorview— these are legacy keys. Always usecomponentOverridesandlayoutinstead.
- Top-level
- Widget rendition pattern (reference an existing WidgetBundle as the root renderer): the renderer file is a thin wrapper that points at the widget by developer name (
"definition": "@widget/c/<widgetDeveloperName>") and maps CLT schema properties to widget attributes via{!$attrs.<schemaPropertyName>}. Do NOT duplicate the widget body insiderenderer.json. Seereferences/widget-rendition.mdfor the full shape, binding rules, and constraints. For the full Apex → Lightning Type → Widget pipeline, use theplatform-lightning-type-widget-coordinateorchestrator instead of this skill. - Root override pattern (most common for fully custom rendering UI with a custom LWC):
renderer.componentOverrides["$"] = { "definition": "c/<yourRendererComponent>", "attributes": { ... } }- Use
{!$attrs.<name>}in attribute mappings when binding schema data to custom renderer component attributes. - CRITICAL: Attribute mappings like
{!$attrs.propertyName}must reference properties that actually exist in your type schema. Referencing non-existent properties will fail validation. - Type matching: Attribute values must match the expected type for the component. For example, if a component expects a string attribute, passing an integer will fail validation.
- Property-level override pattern:
renderer.componentOverrides["<propertyName>"] = { "definition": "es_property_editors/outputText" | "es_property_editors/outputNumber" | "es_property_editors/outputImage" | ... }. Valid renderer components (examples):es_property_editors/outputText,es_property_editors/outputNumber,es_property_editors/outputImage. Avoid input-style components in the renderer.
- Layout pattern for renderer:
renderer.layout.definition = "lightning/verticalLayout"renderer.layout.children[*].definition = "lightning/propertyLayout"withattributes.property = "<propertyName>"- CRITICAL: Same as editor layouts,
lightning/propertyLayoutonly accepts thepropertyattribute. Do NOT addlabel,title, or any other attributes.
- Collection renderer (for root-level
lightning__listTypeproperties): Usecollection.renderer.componentOverrides["$"] = { "definition": "c/<yourListRendererComponent>" }ores_property_editors/genericListTypeRendererto render the list.
- Supported shape: Top-level
- Place files in the correct bundle structure
lightningTypes/<TypeName>/schema.json- (Optional)
lightningTypes/<TypeName>/lightningDesktopGenAi/editor.json - (Optional)
lightningTypes/<TypeName>/lightningDesktopGenAi/renderer.jsonFor Gen AI / Copilot the standard path islightningDesktopGenAi/. Other targets (e.g. Experience Builder, Mobile Copilot, Enhanced Web Chat) use different subfolders when supported:experienceBuilder/,lightningMobileGenAi/,enhancedWebChat/. - (Optional - for widget rendition only)
lightningTypes/<TypeName>/renderer.json
- Configure custom LWC components (if using custom components)
- CRITICAL: Custom LWC components referenced in editor/renderer configs MUST have the correct target configuration in their
-meta.xmlfiles:- For editor components (
c/<componentName>used ineditor.json): The LWC's-meta.xmlfile must include<target>lightning__AgentforceInput</target> - For renderer components (
c/<componentName>used inrenderer.json): The LWC's-meta.xmlfile must include<target>lightning__AgentforceOutput</target>
- For editor components (
- Without the correct target, deployment will fail with:
Invalid target configuration. To use 'c/componentName' as a renderer/editor, your js-meta.xml file must include valid target 'lightning__AgentforceOutput/Input'. - Example
-meta.xmlfor a renderer component:<?xml version="1.0" encoding="UTF-8"?> <LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata"> <apiVersion>60.0</apiVersion> <isExposed>true</isExposed> <targets> <target>lightning__AgentforceOutput</target> </targets> </LightningComponentBundle>
- CRITICAL: Custom LWC components referenced in editor/renderer configs MUST have the correct target configuration in their
Common Deployment Errors
| Error / Symptom | Likely Cause | Fix |
|---|---|---|
| Schema validation fails due to unknown keyword | unevaluatedProperties: false + disallowed keyword (commonly examples, items) | Remove the offending keyword; keep schema minimal |
| Nested object validation failure | Org/channel validation rejects nested object typing in LightningTypeBundle | Use CLT reference (c__<CLTName>) or Apex class types |
| Invalid CLT reference | Referenced CLT doesn't exist in org or incorrect syntax | Deploy the referenced CLT first; c__<CLTName> must match the referenced type’s lightning:type value / FQN / registered identifier, not title |
Invalid or misspelled lightning:type (for example, lightning__richtextType instead of lightning__richTextType) | Incorrect generated type name | Cross-check all lightning:type values against supported type names and correct them before deployment |
| Array property rejected | Use of items (or lightning:type in nested arrays) rejected by validator | For nested arrays: keep only type: "array". For root arrays: use minimal structure; remove items if rejected |
| Apex-based CLT rejected | Extra fields added (e.g., type, properties) | Use only title, optional description, and lightning:type |
| Editor config rejected | Use of invalid patterns (es_property_editors/inputList, itemSchema) or unrecognized top-level keys | Use editor.componentOverrides and editor.layout; keep config minimal |
additionalProperties error on layout attributes | Adding label or other attributes to lightning/propertyLayout | Only use property attribute in lightning/propertyLayout. Remove label, title, or any other attributes |
| Invalid target configuration for custom LWC | Custom LWC component's -meta.xml missing required target (lightning__AgentforceInput or lightning__AgentforceOutput) | Add correct target to LWC's -meta.xml: use lightning__AgentforceInput for editors, lightning__AgentforceOutput for renderers |
| Attribute mapping doesn't exist in type schema | Using {!$attrs.propertyName} where propertyName is not defined in schema | Ensure all attribute mappings reference actual properties in your type schema's properties section |
unevaluatedProperties error on custom LWC renderer for an Apex class CLT | Root override attributes mapping used on an Apex class CLT, which has no properties block to validate against | Remove attributes entirely from the root override; use "componentOverrides": { "$": { "definition": "c/<component>" } } only |
additionalProperties error with deprecated keys | Using propertyRenderers or view in editor/renderer config | Replace deprecated propertyRenderers with componentOverrides and view with layout |
| Type mismatch in component attributes | Passing wrong type for component attribute (e.g., integer instead of string) | Ensure attribute values match the expected type defined by the component |
Verification Checklist
- Root schema has
type: "object",title,lightning:type: "lightning__objectType", andunevaluatedProperties: false - Root schema does not include
exampleswhen strict validation is enabled - No nested object includes
lightning:type: "lightning__objectType" - Arrays are defined minimally (especially nested arrays)
- Only supported primitive
lightning:typeidentifiers are used for leaf properties - Apex class CLTs contain only
title/descriptionandlightning:type: "@apexClassType/..." - Bundle structure and filenames match Lightning Types requirements
- Editor config uses only allowed patterns (no
es_property_editors/inputList, noitemSchema); use valid components (e.g.es_property_editors/inputText,es_property_editors/inputNumber) or customc/components - Renderer config uses output-style components (e.g.
es_property_editors/outputText,es_property_editors/outputNumber) where applicable, not input editors - Layout configurations use
lightning/propertyLayoutwith ONLY thepropertyattribute (nolabel,title, or other attributes) - All attribute mappings (
{!$attrs.propertyName}) reference properties that exist in the type schema - Custom LWC components have correct targets in
-meta.xml:lightning__AgentforceInputfor editors,lightning__AgentforceOutputfor renderers - Root schema does NOT include
"$schema"field
Frequently asked questions about Custom Lightning Types Generator
Similar skills
Rhino 3D Scripting
Streamline your Rhinoceros 3D scripting tasks.
MVVM Toolkit
Streamline ViewModel development with source generators.
FreeCAD Scripts
Generate Python scripts for FreeCAD automation and modeling.
Azure Architecture Builder
Design and deploy Azure infrastructure using natural language.
Command Development
Streamline your command creation for Claude Code.
Create Cowork Plugin
Easily build and package plugins through guided sessions.
