Overview

The LightningComponentBundle metadata type represents a Lightning Web Component (LWC) bundle stored in force-app/main/default/lwc/<componentName>/. A bundle groups the component’s JavaScript controller (.js), HTML template (.html), optional CSS stylesheet (.css), optional SVG icon (.svg), Jest unit tests (__tests__/), and the required XML configuration descriptor (<componentName>.js-meta.xml).

As a Salesforce architect or developer, the .js-meta.xml file is your contract between the component’s @api properties and declarative platform builders (Lightning App Builder, Flow Builder, Experience Builder, and Agentforce). Without properly configuring isExposed, targets, and targetConfigs, a component remains private and can only be embedded as a child inside another LWC.

lwc/invoiceSummary/ invoiceSummary.js (@api recordId, @api maxRows) invoiceSummary.html & invoiceSummary.css invoiceSummary.js-meta.xml (LightningComponentBundle) isExposed: true targets: lightning__RecordPage, lightning__FlowScreen targetConfigs: Property Schemas & Object Filters capabilities: lightning__dynamicComponent ai: Setup with Agentforce Descriptions (v66.0+)

As shown in the architecture diagram above, LightningComponentBundle links your @api decorated JavaScript properties to targetConfigs schemas, controls container placement via targets, unlocks runtime privileges via capabilities, and exposes natural-language metadata to Agentforce via the ai tag.

Prerequisites

  • Permissions: “Customize Application” and “Modify Metadata Through Metadata API Functions” permissions to deploy bundles; “View Setup and Configuration” to query via Tooling API.
  • Naming Convention: Bundle folder and file names must use camelCase starting with a lowercase letter (invoiceSummary), containing only alphanumeric characters and non-consecutive underscores.
  • API Version: Introduced in API version 45.0. Verified against API version 68.0 (Winter ’27).

Key XML Elements in .js-meta.xml

Element Required Purpose & Configuration Rules
apiVersion No (Recommended) Binds the LWC to a specific Salesforce API version (68.0). Determines LWC compiler features and Lightning Web Security (LWS) behavior.
isExposed ✅ Yes Set to true to expose the component to Lightning App Builder, Flow Builder, Experience Builder, or other namespaces.
masterLabel No Friendly title displayed in Setup and builder component palettes. Defaults to the camelCase folder name if omitted.
description No Tooltip description displayed in builders when hovering over the component.
targets No Container types where the component can be dragged (lightning__RecordPage, lightning__AppPage, lightning__HomePage, lightning__FlowScreen, lightning__RecordAction, lightningCommunity__Page).
targetConfigs No Configures @api input/output properties, supported objects, supportedFormFactors (Large, Small), and actionType (ScreenAction, Action) per target.
capabilities No Enables specialized capabilities such as lightning__dynamicComponent, lightning__ServerRenderable, lightning__ServiceCloudVoiceToolkitApi, or lightningCommunity__RelaxedCSP.
ai No Provides <description> and <property name="..." aiDescription="..."/> tags for Setup with Agentforce (API 66.0+).

Release: Spring ’26

Starting in API version 66.0, the <ai> tag in LightningComponentBundle allows Setup with Agentforce to understand what your custom LWC does and automatically place and configure it on agent-generated FlexiPage layouts.

Querying LightningComponentBundle via Tooling API

LightningComponentBundle and its child LightningComponentResource are available exclusively through the Tooling API (sf data query --use-tooling-api).

1. List All Exposed LWC Bundles and Their API Versions

Identify components exposed to App Builder or running on outdated API versions:

SOQL
SELECT Id, DeveloperName, MasterLabel, ApiVersion,
       IsExposed, ManageableState, Description, LastModifiedDate
FROM LightningComponentBundle
WHERE ManageableState = 'unmanaged'
ORDER BY ApiVersion ASC, DeveloperName ASC

2. Search Inside LWC Source Files (JS, HTML, XML) via Tooling API

Query LightningComponentResource to inspect file paths, formats (js, html, css), and source code across all LWC bundles:

SOQL
SELECT Id, LightningComponentBundle.DeveloperName, FilePath, Format, LastModifiedDate
FROM LightningComponentResource
WHERE LightningComponentBundle.ManageableState = 'unmanaged'
ORDER BY LightningComponentBundle.DeveloperName ASC

Example

The following .js-meta.xml configures an invoiceSummary LWC for three distinct contexts: an Account/Invoice Record Page (restricted to Desktop and Mobile form factors), a Screen Flow (with input and output variables), and a headless Quick Action, plus Agentforce AI metadata.

force-app/main/default/lwc/invoiceSummary/invoiceSummary.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>68.0</apiVersion>
    <isExposed>true</isExposed>
    <masterLabel>Invoice Summary Card</masterLabel>
    <description>Displays overdue and open invoices with one-click payment actions.</description>
    <capabilities>
        <capability>lightning__dynamicComponent</capability>
    </capabilities>
    <targets>
        <target>lightning__RecordPage</target>
        <target>lightning__AppPage</target>
        <target>lightning__FlowScreen</target>
        <target>lightning__RecordAction</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightning__RecordPage">
            <objects>
                <object>Account</object>
                <object>Invoice__c</object>
            </objects>
            <property name="maxRows" type="Integer" label="Max Invoices Shown" default="5" min="1" max="50"
                      description="Maximum number of recent invoices to display in the table." />
            <property name="showOverdueOnly" type="Boolean" label="Show Overdue Only" default="false" />
            <supportedFormFactors>
                <supportedFormFactor type="Large" />
                <supportedFormFactor type="Small" />
            </supportedFormFactors>
        </targetConfig>
        <targetConfig targets="lightning__FlowScreen">
            <property name="recordId" type="String" label="Account or Invoice ID" role="inputOnly" required="true" />
            <property name="selectedInvoiceId" type="String" label="Selected Invoice ID" role="outputOnly" />
        </targetConfig>
        <targetConfig targets="lightning__RecordAction">
            <actionType>ScreenAction</actionType>
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>

The corresponding JavaScript file must declare every property referenced in <targetConfigs> with the @api decorator:

force-app/main/default/lwc/invoiceSummary/invoiceSummary.js
import { LightningElement, api } from 'lwc';

export default class InvoiceSummary extends LightningElement {
    @api recordId;
    @api maxRows = 5;
    @api showOverdueOnly = false;
    @api selectedInvoiceId;

    @api invoke() {
        // Executed when actionType is Action (headless quick action)
    }
}

Limits and Gotchas

  • Every <property> Requires @api: If you define <property name="maxRows" .../> in .js-meta.xml without declaring @api maxRows in the .js file, the deployment fails immediately with a compilation error.
  • Boolean Properties Cannot Default to Unset in Builders: For type="Boolean" properties in targetConfig, always explicitly provide default="true" or default="false".
  • Deleting a Property Referenced on a FlexiPage: You cannot remove a <property> from .js-meta.xml or set <isExposed>false</isExposed> while any active FlexiPage or Flow in the target org references that component or property.
  • Case Sensitivity Warning: Deploying lwc/myComponent when lwc/MyComponent or an Aura component named myComponent already exists in the org will fail due to namespace collision.

Frequently asked questions

Why does my Lightning Web Component not appear in Lightning App Builder?

In the component's .js-meta.xml file, isExposed must be set to true and at least one page target (such as lightning__RecordPage or lightning__AppPage) must be listed inside the targets element.

What is the difference between targets and capabilities in .js-meta.xml?

Targets define where a component can be placed (such as Record Pages, Flow Screens, or Experience Cloud). Capabilities define special runtime features the component can use, such as lightning__dynamicComponent or lightning__ServerRenderable.

How do I restrict an LWC to only appear on specific object Record Pages?

Add a targetConfig for lightning__RecordPage in your .js-meta.xml file and list the allowed object API names (such as Account or Invoice__c) inside the objects element.

How do I query LightningComponentBundle metadata using SOQL?

Use the Tooling API (--use-tooling-api) to query LightningComponentBundle for bundle-level settings like ApiVersion, IsExposed, and RuntimeNamespace, or LightningComponentResource to inspect individual HTML, JS, and CSS files.

Can I rename a LightningComponentBundle with a lowercase first letter matching an Aura component?

No. An LWC and an Aura component cannot share the same name in the same namespace. Additionally, LWC folder and file names must begin with a lowercase letter and use camelCase.

What does the ai element in LightningComponentBundle do?

Introduced in API version 66.0, the ai tag provides a natural-language component and property description that Setup with Agentforce uses to automatically select and configure the LWC on agent-generated Lightning pages.

Comments

Questions, corrections and tips are welcome. Comments are GitHub Discussions, so you sign in with GitHub.