Sf lwc
Salesforce development skills for AI coding agents - Apex, Flows, LWC, SOQL, security, deployments. Works with Claude Code, Cursor, Codex, and 50+ tools.
npx -y skills add Clientell-Ai/salesforce-skills --skill sf-lwcAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 11 stars11 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Scaffold Lightning Web Components with HTML templates, JS controllers, CSS with SLDS compliance, js-meta.xml config, and Jest tests. Use when asked about Lightning Web Components, LWC, component scaffolding, or Jest tests for LWC. Activate on .js-meta.xml files, mentions of "LWC", "Lightning Web Component", "wire adapter", "lightning component", or "@api/@wire/@track decorators".
The file declares its own license as Apache-2.0. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
8.8 KB, as published. Nobody here has run it
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-casewithc-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:
getRecordwire adapter — read records with field-level securitycreateRecord,updateRecord,deleteRecord— imperative CRUDgetObjectInfo,getPicklistValues— metadata accessrefreshApex()— invalidate wire cache after mutations- When to use: Simple CRUD. Use Apex wire for complex queries or business logic.
Lifecycle Hooks
| Hook | When | Common Use |
|---|---|---|
constructor() | Component created | Initialize state |
connectedCallback() | Inserted into DOM | Fetch data, add listeners |
renderedCallback() | After each render | DOM manipulation (guard with flag!) |
disconnectedCallback() | Removed from DOM | Cleanup listeners, unsubscribe LMS |
errorCallback(error, stack) | Child error | Error boundary, logging |
Navigation
Use NavigationMixin with page reference types:
standard__recordPage— view/edit/clone records (requiresrecordId,actionName)standard__objectPage— object home/list/new (requiresobjectApiName,actionName)standard__namedPage— standard pages (home, chatter, filePreview)standard__webPage— external URLs (requiresurl)
Lightning Message Service (LMS)
Cross-DOM communication between LWC, Aura, and Visualforce:
- Define message channel in
.messageChannel-meta.xml publish(messageContext, channel, payload)to sendsubscribe(messageContext, channel, handler, {scope: APPLICATION_SCOPE})to receive- Always
unsubscribe()indisconnectedCallback()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 — usethis.template.querySelector()inside
Rules
- Always use SLDS classes for styling — avoid custom CSS when SLDS has a utility
- Use
@apifor public properties, reactive by default - Use
@wirefor 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-formfor simple CRUD - Dispatch custom events for child-to-parent communication
- Use
MessageChannelfor cross-DOM communication
Gotchas
@trackis 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 vialoadScript()from Static Resources @apiproperties 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
- Understand the component requirements
- Check for existing components that can be extended
- Generate all bundle files (HTML, JS, CSS, meta.xml)
- Generate Jest test file with mock data
- 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