Org Skills

Lightning Web Components

Always-on rules for writing Salesforce Lightning Web Components, their templates, styles, metadata and Jest tests.

Raw Source
What it isAlways-on coding rules. GitHub Copilot applies them to files matching **/lwc/**; the Claude Code version is a path-scoped rule generated from the same file. Why use instructions →

Install

This repository (recommended)

Adds .github/instructions/lwc.instructions.md — commit it so everyone's Copilot follows the same rules.

npx -y github:AGCO-Global/org-skills add instructions lwc

Just for me, every repository

Save it in your user profile instead.

npx -y github:AGCO-Global/org-skills add instructions lwc --user

Use it

Nothing to invoke — edit a matching file and Copilot picks the rules up. Adjust applyTo if your repository layout differs.

This repository (recommended)

Adds .claude/rules/lwc.md — commit it. Claude loads it when it reads a matching file.

npx -y github:AGCO-Global/org-skills add instructions lwc --tool claude

Just for me, every repository

Save it in your user profile instead.

npx -y github:AGCO-Global/org-skills add instructions lwc --tool claude --user

Use it

Nothing to invoke. Adjust the paths globs if your repository layout differs.

Commands run in your repository folder and need Node.js 20+. They use your normal git sign-in to GitHub, so they work while the repository is private. Run npx -y github:AGCO-Global/org-skills list to see everything available.

Settings

name: "Lightning Web Components"
description: "Always-on rules for writing Salesforce Lightning Web Components, their templates, styles, metadata and Jest tests."
applyTo: "**/lwc/**"

Instructions Copilot follows

Lightning Web Components rules

Get data through the platform's cached services first and write Apex last; every Apex method is code to secure, test and maintain.

Data access

  • Use base record forms (lightning-record-form, -view-form, -edit-form) for single-record view and edit. No Apex, FLS enforced, cached.
  • Read record fields with @wire(getRecord) and getFieldValue; write with createRecord/updateRecord/deleteRecord from lightning/uiRecordApi.
  • Use getObjectInfo, getPicklistValues, related list and GraphQL adapters before custom Apex. They respect record types and layouts.
  • Use @wire for reads that should stay in sync; wired Apex must be @AuraEnabled(cacheable=true) and do no DML.
  • Call Apex imperatively for mutations and user-triggered reads; debounce search input. One call per keystroke burns limits.
  • After an imperative mutation, call refreshApex(this.wiredResult) or notifyRecordUpdateAvailable so other components update.
  • Guard wire handlers against undefined data on first render; reactive params use $recordId.
  • Prefer several small cacheable wires over one call returning the whole page; paginate server-side, never ship thousands of rows.

Reactivity and lifecycle

  • Reassign arrays and objects (this.items = [...this.items, item]) instead of mutating them; in-place mutation does not re-render.
  • Use getters for derived values; do not store computed state.
  • Use @track only for deep mutation you cannot replace with reassignment.
  • Set up subscriptions in connectedCallback and remove them in disconnectedCallback. Leaks otherwise.
  • Never fetch data in renderedCallback, and guard any work there with a flag. It runs on every render.
  • Use lwc:if/lwc:elseif/lwc:else (not if:true), key on every for:each item, and lwc:ref for element access.

Events and communication

  • Parent to child through @api properties and methods; child to parent through CustomEvent with data in detail.
  • Name events lowercase with no on prefix or hyphens; keep bubbles and composed false unless crossing a boundary is required.
  • Use Lightning Message Service with a MessageChannel for unrelated components; no pub/sub helpers or window globals.
  • Surface errors with ShowToastEvent or an inline message near the action; flatten error.body into readable text.

Styling and accessibility

  • Use Lightning Base Components before custom markup. They are accessible and themed.
  • Customise with SLDS styling hooks (--slds-g-*, --slds-c-*); never reach into base component internals.
  • Keep CSS scoped to the component with :host; no hard-coded colours where a token exists.
  • Use Custom Labels (@salesforce/label/c.X) for all user-facing text. Needed for translation.
  • Give icon-only buttons alternative-text and every input a label (use variant="label-hidden" to hide it visually).
  • Add role, aria-*, focus handling and keyboard support to any raw interactive HTML.

Security and runtime

  • Respect Lightning Web Security/Locker: no eval, no innerHTML with user data, no reaching into other components' DOM.
  • Load third-party libraries from static resources with loadScript/loadStyle, never from a CDN at runtime.
  • Treat hiding fields in the UI as UX, not security; Apex must enforce access with USER_MODE and with sharing.
  • Never put secrets in JavaScript or static resources; add external URLs to CSP Trusted Sites.
  • Declare targets and typed targetConfigs with defaults in js-meta.xml so admins can configure components.

Tests

  • Write Jest tests with @salesforce/sfdx-lwc-jest in __tests__/<component>.test.js, one behaviour per it.
  • Mock Apex with jest.mock('@salesforce/apex/...', () => ({ default: jest.fn() }), { virtual: true }); drive wires with .emit(data)/.error(err) and imperative calls with mockResolvedValue/mockRejectedValue.
  • Emit LDS adapters (getRecord.emit(fixture)) with JSON fixtures in __tests__/data/.
  • await a promise flush after every emit or action, and remove elements from document.body in afterEach. Prevents flaky, leaking tests.
  • Assert rendered output, dispatched events, Apex parameters and error branches, and run toBeAccessible() from sa11y.

Go deeper: for larger tasks use the lwc-development, salesforce-frontend-architecture and salesforce-frontend-testing skills, and frontend-code-review before opening a pull request.