Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
forcedotcom avatar

Salesforce Custom Lightning Type

  • 1 installs
  • 787 repo stars
  • Updated August 5, 2026
  • forcedotcom/afv-library

Creates Custom Lightning Types (CLTs), JSON Schema type definitions for Einstein Agent actions and structured input/output with editor/renderer config.

About

Generates CustomLightningType metadata as JSON Schema-based type definitions driving Einstein Agent action inputs/outputs and editor/renderer UI. A developer uses it to define structured type schemas for Lightning Platform agent actions.

  • Enforces CLT metaschema rules like unevaluatedProperties:false and restricted array items
  • Supports standard lightning types or Apex class types

Salesforce Custom Lightning Type by the numbers

  • 1 all-time installs (skills.sh)
  • Ranked #14,102 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/forcedotcom/afv-library --skill salesforce-custom-lightning-type

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs1
repo stars787
Last updatedAugust 5, 2026
Repositoryforcedotcom/afv-library

What it does

Creates Custom Lightning Types (CLTs), JSON Schema type definitions for Einstein Agent actions and structured input/output with editor/renderer config.

Files

SKILL.mdMarkdownGitHub ↗

When 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 standard Lightning types when the structure is simple and can be expressed with properties and supported primitive lightning:type identifiers.
  • 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)

  • Root object schemas MUST include:
  • "type": "object"
  • "title"
  • "lightning:type": "lightning__objectType"
  • "unevaluatedProperties": false
  • "unevaluatedProperties" is enforced as false by the CLT metaschema. Do not set it to true.
  • Root object schemas MUST NOT include "examples" when "unevaluatedProperties": false is set.
  • Nested objects (inside `properties`) MUST NOT set "lightning:type": "lightning__objectType".
  • Nested objects should be plain JSON Schema objects (type, properties, optional required, optional unevaluatedProperties).
  • List/array properties are highly restricted by the CLT metaschema:
  • CRITICAL LIMITATION: the CLT metaschema may reject the items keyword entirely. Treat items as 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"
  • 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"
  • When `"unevaluatedProperties": false` is set, any unknown keyword will fail validation. Prefer removing keywords over relaxing strictness.
  • Apex class CLTs are minimal:
  • Include only title, description (optional), and lightning:type set to @apexClassType/....
  • Do not add type, properties, required, or unevaluatedProperties.

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_cms where not permitted).
  • Object type validation: the CLT root is validated to ensure lightning:type is exactly lightning__objectType.

Primitive Types & Constraints

  • lightning__textType
  • Max length 255
  • lightning__multilineTextType
  • Max length 2000
  • lightning__richTextType
  • Max length 100000
  • lightning__urlType
  • Max length 2000
  • Optional lightning:allowedUrlSchemes enum values: https, http, relative, mailto, tel
  • lightning__dateType
  • Data pattern: YYYY-MM-DD
  • lightning__timeType
  • Data pattern: HH:MM:SS.sssZ
  • lightning__dateTimeType
  • Data shape is an object with required dateTime and optional timeZone
  • lightning__numberType
  • Decimal numbers; optional maximum, minimum, multipleOf
  • lightning__integerType
  • Whole numbers only; optional maximum, minimum
  • lightning__booleanType
  • true/false

Allowed Property-Level Keywords

When strict validation is enabled (unevaluatedProperties: false), keep each property minimal and prefer only keywords known to be allowed:

  • title, description, einstein:description
  • type (when used, ensure it matches the chosen lightning:type)
  • lightning:type
  • maximum, minimum, multipleOf (numeric)
  • maxLength, minLength (string)
  • const, enum
  • lightning:textIndexed, lightning:supportsPersonalization, lightning:localizable
  • lightning:uiOptions, lightning:allowedUrlSchemes
  • lightning:tags (metaschema restricts values; currently flow is the only known allowed tag)

Generation Workflow

1. 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.

2. Draft `schema.json`

  • Start with the root object structure (required root fields).
  • Add properties using valid primitive lightning:type identifiers.
  • For nested objects: omit lightning:type and keep keywords minimal.
  • For arrays: follow the strict list rules (avoid items; avoid lightning:type on nested arrays).

3. (Optional) Draft `editor.json` (only if custom UI is required)

  • Supported shape: Top-level editor object with editor.componentOverrides and editor.layout.
  • Top-level editor object.
  • Use editor.componentOverrides for component overrides.
  • Use editor.layout for layout.
  • 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.
  • 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 use es_property_editors/inputList.
  • Collection editor (for root-level lightning__listType properties): Use a collection-level override so the list is edited by a custom component: collection.editor.componentOverrides["$"] = { "definition": "c/<yourCollectionEditorComponent>" }. Alternatively, use editor.layout with lightning/propertyLayout and attributes.property = "<listPropertyName>" for default list editing.
  • Layout pattern:
  • editor.layout.definition = "lightning/verticalLayout"
  • editor.layout.children[*].definition = "lightning/propertyLayout" with attributes.property = "<propertyName>"
  • Avoid known-invalid patterns:
  • Do not use es_property_editors/inputList.
  • Do not use itemSchema attributes.

4. (Optional) Draft `renderer.json` (only if custom UI is required)

  • Supported shape: Top-level renderer object with renderer.componentOverrides and renderer.layout.
  • Top-level renderer object.
  • Use renderer.componentOverrides for component overrides.
  • Use renderer.layout for layout.
  • Root override pattern (most common for fully custom rendering UI):
  • renderer.componentOverrides["$"] = { "definition": "c/<yourRendererComponent>", "attributes": { ... } }
  • Use {!$attrs.<name>} in attribute mappings when binding schema data to custom renderer component attributes.
  • 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.
  • Collection renderer (for root-level lightning__listType properties): Use collection.renderer.componentOverrides["$"] = { "definition": "c/<yourListRendererComponent>" } or es_property_editors/genericListTypeRenderer to render the list.

5. Place files in the correct bundle structure

  • lightningTypes/<TypeName>/schema.json
  • (Optional) lightningTypes/<TypeName>/lightningDesktopGenAi/editor.json
  • (Optional) lightningTypes/<TypeName>/lightningDesktopGenAi/renderer.json
  • For Gen AI / Copilot the standard path is lightningDesktopGenAi/. Other targets (e.g. Experience Builder, Mobile Copilot, Enhanced Web Chat) use different subfolders when supported: experienceBuilder/, lightningMobileGenAi/, enhancedWebChat/.

6. Deploy and validate

  • Deploy the bundle using your org's standard metadata deployment flow (e.g. Salesforce CLI or IDE). The MCP client or tooling in use should provide or integrate with the appropriate deploy/retrieve commands for Lightning Type bundles.
  • Validate incrementally: if deployment fails, remove disallowed keywords first (especially examples, items, nested lightning:type).

Common Deployment Errors

Error / SymptomLikely CauseFix
Schema validation fails due to unknown keywordunevaluatedProperties: false + disallowed keyword (commonly examples, items)Remove the offending keyword; keep schema minimal
Nested object validation failureNested object includes lightning:type: lightning__objectTypeRemove lightning:type from nested objects
Array property rejectedUse of items (or lightning:type in nested arrays) rejected by validatorFor nested arrays: keep only type: "array". For root arrays: use minimal structure; remove items if rejected
Apex-based CLT rejectedExtra fields added (e.g., type, properties)Use only title, optional description, and lightning:type
Editor config rejectedUse of invalid patterns (es_property_editors/inputList, itemSchema) or unrecognized top-level keysUse editor.componentOverrides and editor.layout; keep config minimal

Verification Checklist

  • [ ] Root schema has type: "object", title, lightning:type: "lightning__objectType", and unevaluatedProperties: false
  • [ ] Root schema does not include examples when strict validation is enabled
  • [ ] No nested object includes lightning:type: "lightning__objectType"
  • [ ] Arrays are defined minimally (especially nested arrays)
  • [ ] Only supported primitive lightning:type identifiers are used for leaf properties
  • [ ] Apex class CLTs contain only title/description and lightning:type: "@apexClassType/..."
  • [ ] Bundle structure and filenames match Lightning Types requirements
  • [ ] Editor config uses only allowed patterns (no es_property_editors/inputList, no itemSchema); use valid components (e.g. es_property_editors/inputText, es_property_editors/inputNumber) or custom c/ components
  • [ ] Renderer config uses output-style components (e.g. es_property_editors/outputText, es_property_editors/outputNumber) where applicable, not input editors

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.