Install
$ agentstack add skill-jiten-singh-shahi-salesforce-claude-code-sf-lwc-development ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
LWC Development
Lightning Web Components (LWC) is Salesforce's modern component model based on web standards — Custom Elements, Shadow DOM, and ES modules.
When to Use
- When building new Lightning Web Components from scratch
- When migrating Aura components to LWC
- When debugging reactive property or wire service issues
- When implementing parent-child communication with events or @api
- When adding LWC components to record pages, app pages, or Experience Cloud sites
@../reference/LWCPATTERNS.md
Component Creation Procedure
Every LWC component is a folder with at minimum an HTML template and a JavaScript class.
force-app/main/default/lwc/
accountList/
accountList.html
{errorMessage}
{account.Name}
Step 2 — JavaScript Class
import { LightningElement, api, wire } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { NavigationMixin } from 'lightning/navigation';
import getAccounts from '@salesforce/apex/AccountsController.getAccounts';
export default class AccountList extends NavigationMixin(LightningElement) {
@api recordId;
@api maxRecords = 10;
accounts = [];
isLoading = false;
error;
get hasError() { return this.error !== undefined; }
get isEmpty() { return !this.isLoading && this.accounts.length === 0; }
get errorMessage() {
return this.error?.body?.message ?? this.error?.message ?? 'An unknown error occurred.';
}
connectedCallback() { this.loadAccounts(); }
handleViewAccount(event) {
this[NavigationMixin.Navigate]({
type: 'standard__recordPage',
attributes: { recordId: event.currentTarget.dataset.id,
objectApiName: 'Account', actionName: 'view' }
});
}
async loadAccounts() {
this.isLoading = true;
this.error = undefined;
try {
this.accounts = await getAccounts({
searchTerm: this.searchTerm, maxRecords: this.maxRecords
});
} catch (error) {
this.error = error;
} finally {
this.isLoading = false;
}
}
}
Step 3 — Meta XML
66.0
true
lightning__RecordPage
lightning__AppPage
lightning__HomePage
Wire Service Usage
The wire service declaratively connects components to Salesforce data and re-runs when reactive parameters change.
Wire with Apex
import { LightningElement, wire, api } from 'lwc';
import { refreshApex } from '@salesforce/apex';
import getAccountDetails from '@salesforce/apex/AccountsController.getAccountDetails';
export default class AccountDetails extends LightningElement {
@api recordId;
_wiredResult;
@wire(getAccountDetails, { accountId: '$recordId' })
wiredAccount(result) {
this._wiredResult = result;
if (result.data) {
this.account = result.data;
this.error = undefined;
} else if (result.error) {
this.error = result.error;
this.account = undefined;
}
}
async handleSave(event) {
await updateAccount({ accountId: this.recordId, fields: event.detail.fields });
await refreshApex(this._wiredResult);
}
}
Wire with Lightning Data Service
import { LightningElement, api, wire } from 'lwc';
import { getRecord, getFieldValue, updateRecord } from 'lightning/uiRecordApi';
import ACCOUNT_NAME from '@salesforce/schema/Account.Name';
import ACCOUNT_INDUSTRY from '@salesforce/schema/Account.Industry';
export default class AccountHeader extends LightningElement {
@api recordId;
@wire(getRecord, { recordId: '$recordId', fields: [ACCOUNT_NAME, ACCOUNT_INDUSTRY] })
account;
get name() { return getFieldValue(this.account.data, ACCOUNT_NAME); }
get industry() { return getFieldValue(this.account.data, ACCOUNT_INDUSTRY); }
}
Event Handling — Component Communication
Child to Parent: Custom Events
// child: opportunityCard.js
handleSelect() {
this.dispatchEvent(new CustomEvent('opportunityselect', {
detail: { opportunityId: this.opportunity.Id },
bubbles: false, composed: false
}));
}
Cross-Component: Lightning Message Service
import { publish, subscribe, unsubscribe, MessageContext, APPLICATION_SCOPE }
from 'lightning/messageService';
import CHANNEL from '@salesforce/messageChannel/OpportunitySelected__c';
// Publisher
@wire(MessageContext) messageContext;
handleSelect(event) {
publish(this.messageContext, CHANNEL, { opportunityId: event.target.dataset.id });
}
// Subscriber
connectedCallback() {
this.subscription = subscribe(this.messageContext, CHANNEL,
(msg) => this.handleMessage(msg), { scope: APPLICATION_SCOPE });
}
disconnectedCallback() { unsubscribe(this.subscription); }
Slots — Composition Patterns
Default Header
Edit Account
Light DOM
Renders component markup directly into the parent DOM (no shadow boundary).
export default class ThemedComponent extends LightningElement {
static renderMode = 'light';
}
Use for: global CSS theming, third-party library integration, Experience Cloud sites, simple leaf components. Query with this.querySelector() instead of this.template.querySelector().
Spring '26 Features
SLDS 2.0
Use --slds-c-* styling hooks (replaces --lwc-* design tokens). Run npx slds-lint to check compliance.
TypeScript Support
npm install --save-dev @salesforce/lightning-types
Complex Template Expressions (Beta)
{account.Name ?? 'Unknown Account'}
{formatRevenue(account.AnnualRevenue)}
Use getters for production code until this reaches GA.
LWC in Screen Flows
Expose components as Flow screen actions via lightning__FlowScreen target. Implement @api validate() for Flow navigation validation.
Related
Guardrails
- sf-lwc-constraints — Enforced rules for LWC naming, reactivity, security, and accessibility
Agents
- sf-lwc-agent — For interactive, in-depth LWC review guidance
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: jiten-singh-shahi
- Source: jiten-singh-shahi/salesforce-claude-code
- License: MIT
- Homepage: https://www.npmjs.com/package/scc-universal
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.