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

Sf Lwc

  • 41 installs
  • 12 repo stars
  • Updated July 14, 2026
  • clientell-ai/salesforce-skills

sf-lwc is an agent skill that documents Salesforce Lightning Web Component patterns for LDS wire adapters and UI Record API usage.

About

sf-lwc is a patterns reference skill for solo builders and small teams building on Salesforce who need Lightning Web Components that follow platform-native data access. Instead of routing every screen through custom Apex, the skill documents how to wire getRecord with explicit schema imports, derive display values safely, and pull object metadata through getObjectInfo. It is aimed at agents and developers using Claude Code, Cursor, or Codex inside a Salesforce DX workspace who want consistent, reviewable LWC that respects field-level security patterns via optionalFields where appropriate. Use it during feature work when you are implementing record detail panels, related lookups, or metadata-driven forms and need authoritative snippets rather than outdated Aura-era examples. The content is reference-oriented: you invoke it while coding LWCs, paste-adapt the patterns, and keep your components aligned with Lightning UI APIs for maintainability and faster security review on enterprise orgs.

  • Lightning Data Service wire patterns with @salesforce/schema field imports
  • getRecord, getFieldValue, getFieldDisplayValue, and optionalFields for FLS-safe reads
  • getObjectInfo and uiObjectInfoApi metadata wiring examples
  • Copy-paste JavaScript snippets aligned to Salesforce UI Record API conventions

Sf Lwc by the numbers

  • 41 all-time installs (skills.sh)
  • Ranked #1,367 of 2,245 Frontend Development skills by installs in the Skillselion catalog
  • Security screen: LOW risk (skills.sh audit)
  • Data as of Jul 28, 2026 (Skillselion catalog sync)
npx skills add https://github.com/clientell-ai/salesforce-skills --skill sf-lwc

Add your badge

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

Listed on Skillselion
Installs41
repo stars12
Security audit3 / 3 scanners passed
Last updatedJuly 14, 2026
Repositoryclientell-ai/salesforce-skills

What it does

Ship Salesforce Lightning Web Components with correct LDS wire adapters, schema imports, and UI API patterns instead of guessing Apex-heavy data access.

Who is it for?

consultants or ISVs shipping Experience Cloud or internal Salesforce apps who want agent-assisted LWC that stays on-platform.

Skip if: Teams not on Salesforce, pure Aura-only legacy stacks, or backend-only Apex integration work with no UI surface.

When should I use this skill?

When implementing or reviewing Salesforce LWCs that read records or object metadata via Lightning UI APIs.

What you get

Your agent emits LWC code that uses schema-backed wires, optionalFields where needed, and object metadata APIs consistent with Salesforce best practices.

  • LWC JavaScript modules using LDS wires
  • Record-detail and metadata-driven UI snippets

Files

SKILL.mdMarkdownGitHub ↗

LWC Scaffolder

You are a Salesforce Lightning Web Component specialist. Generate complete, production-ready LWC bundles.

LWC Bundle Structure

Every LWC consists of these files in force-app/main/default/lwc/componentName/:

myComponent/
├── myComponent.html          # Template
├── myComponent.js            # Controller
├── myComponent.css           # Styles (SLDS-compliant)
├── myComponent.js-meta.xml   # Configuration
└── __tests__/
    └── myComponent.test.js   # Jest tests

Naming Conventions

  • Bundle folder: camelCase (e.g., accountList)
  • HTML markup: kebab-case with c- namespace (e.g., <c-account-list>)
  • JS class: PascalCase (e.g., AccountList)
  • CSS: follows component name

JavaScript Controller Pattern

import { LightningElement, api, wire, track } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { NavigationMixin } from 'lightning/navigation';
import getRecords from '@salesforce/apex/MyController.getRecords';
import ACCOUNT_NAME from '@salesforce/schema/Account.Name';

export default class MyComponent extends NavigationMixin(LightningElement) {
    @api recordId;
    @track records = [];
    error;
    isLoading = false;

    @wire(getRecords, { recordId: '$recordId' })
    wiredRecords({ error, data }) {
        if (data) {
            this.records = data;
            this.error = undefined;
        } else if (error) {
            this.error = error;
            this.records = [];
        }
    }

    handleAction() {
        this.isLoading = true;
        imperativeMethod({ param: this.recordId })
            .then(result => {
                this.dispatchEvent(new ShowToastEvent({
                    title: 'Success',
                    message: 'Operation completed',
                    variant: 'success'
                }));
            })
            .catch(error => {
                this.dispatchEvent(new ShowToastEvent({
                    title: 'Error',
                    message: error.body?.message || 'An error occurred',
                    variant: 'error'
                }));
            })
            .finally(() => {
                this.isLoading = false;
            });
    }
}

Meta XML Configuration

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>62.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__RecordPage</target>
        <target>lightning__AppPage</target>
        <target>lightning__HomePage</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightning__RecordPage">
            <objects>
                <object>Account</object>
            </objects>
            <property name="title" type="String" default="My Component"/>
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>

Jest Test Pattern

import { createElement } from 'lwc';
import MyComponent from 'c/myComponent';
import getRecords from '@salesforce/apex/MyController.getRecords';

// Mock Apex method
jest.mock('@salesforce/apex/MyController.getRecords', () => ({
    default: jest.fn()
}), { virtual: true });

const MOCK_DATA = [
    { Id: '001xx000003ABCDEF', Name: 'Test Account' }
];

describe('c-my-component', () => {
    afterEach(() => {
        while (document.body.firstChild) {
            document.body.removeChild(document.body.firstChild);
        }
        jest.clearAllMocks();
    });

    it('renders records when data is returned', async () => {
        getRecords.mockResolvedValue(MOCK_DATA);

        const element = createElement('c-my-component', { is: MyComponent });
        element.recordId = '001xx000003ABCDEF';
        document.body.appendChild(element);

        await Promise.resolve();

        const items = element.shadowRoot.querySelectorAll('.record-item');
        expect(items.length).toBe(1);
    });

    it('shows error when apex call fails', async () => {
        getRecords.mockRejectedValue(new Error('Test error'));

        const element = createElement('c-my-component', { is: MyComponent });
        document.body.appendChild(element);

        await Promise.resolve();

        const errorEl = element.shadowRoot.querySelector('.error-message');
        expect(errorEl).toBeTruthy();
    });
});

Lightning Data Service (LDS)

Use lightning/uiRecordApi for CRUD without Apex:

  • getRecord wire adapter — read records with field-level security
  • createRecord, updateRecord, deleteRecord — imperative CRUD
  • getObjectInfo, getPicklistValues — metadata access
  • refreshApex() — invalidate wire cache after mutations
  • When to use: Simple CRUD. Use Apex wire for complex queries or business logic.

Lifecycle Hooks

HookWhenCommon Use
constructor()Component createdInitialize state
connectedCallback()Inserted into DOMFetch data, add listeners
renderedCallback()After each renderDOM manipulation (guard with flag!)
disconnectedCallback()Removed from DOMCleanup listeners, unsubscribe LMS
errorCallback(error, stack)Child errorError boundary, logging

Navigation

Use NavigationMixin with page reference types:

  • standard__recordPage — view/edit/clone records (requires recordId, actionName)
  • standard__objectPage — object home/list/new (requires objectApiName, actionName)
  • standard__namedPage — standard pages (home, chatter, filePreview)
  • standard__webPage — external URLs (requires url)

Lightning Message Service (LMS)

Cross-DOM communication between LWC, Aura, and Visualforce:

  • Define message channel in .messageChannel-meta.xml
  • publish(messageContext, channel, payload) to send
  • subscribe(messageContext, channel, handler, {scope: APPLICATION_SCOPE}) to receive
  • Always unsubscribe() in disconnectedCallback() to prevent memory leaks

Shadow DOM vs Light DOM

  • Shadow DOM (default): CSS isolation, encapsulated DOM — use for most components
  • Light DOM (lwc:dom="light"): No encapsulation — use when you need cross-component ARIA references, global CSS, or third-party library DOM access
  • Shadow DOM blocks document.querySelector() from outside — use this.template.querySelector() inside

Rules

  • Always use SLDS classes for styling — avoid custom CSS when SLDS has a utility
  • Use @api for public properties, reactive by default
  • Use @wire for declarative data fetching
  • Use imperative Apex calls for user-initiated actions
  • Handle loading states and errors in every component
  • Use lightning-record-form / lightning-record-edit-form for simple CRUD
  • Dispatch custom events for child-to-parent communication
  • Use MessageChannel for cross-DOM communication

Gotchas

  • @track is deprecated — all properties are reactive by default since API v40+
  • renderedCallback() fires after EVERY render — always guard with a boolean flag to prevent infinite loops
  • LDS cache is NOT automatically refreshed — call refreshApex(wiredProperty) after imperative mutations
  • LMS subscriptions MUST unsubscribe in disconnectedCallback() to prevent memory leaks
  • Shadow DOM blocks ID-based ARIA references (aria-labelledby) across components — use Light DOM for accessibility
  • CSP blocks eval(), new Function(), and inline <script> — load third-party libraries via loadScript() from Static Resources
  • @api properties are read-only in the component — parent sets them, child cannot mutate
  • Wire adapters re-fire when reactive parameters change — avoid unnecessary parameter changes

Workflow

1. Understand the component requirements 2. Check for existing components that can be extended 3. Generate all bundle files (HTML, JS, CSS, meta.xml) 4. Generate Jest test file with mock data 5. Deploy: sf project deploy start -d force-app/main/default/lwc/componentName/

References

  • LWC Patterns — LDS, navigation, LMS, datatable, custom events, slots, accessibility, SLDS, third-party libs, dynamic components, Experience Cloud

Related skills

How it compares

Use as a focused LWC snippet reference instead of generic React or Vue frontend skills that ignore Lightning UI APIs.

FAQ

Who is sf-lwc for?

Developers and small teams implementing Salesforce Lightning Web Components who want correct LDS and uiRecordApi patterns while pair-programming with an AI agent.

When should I use sf-lwc?

Use it in the Build phase while coding record pages, related-field displays, or metadata-driven forms; also when refactoring LWCs away from unnecessary Apex controllers.

Is sf-lwc safe to install?

Review the Security Audits panel on this Prism page and your org’s allowed package sources before trusting any third-party skill in a production Salesforce workspace.

Frontend Developmentfrontendintegrations

This week in AI coding

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

unsubscribe anytime.