Instruction file imported from dbruun/GHCP-Instruction-Examples (
.github/instructions/salesforce.lwc.instructions.md). Copyright stays with the author.
Salesforce Lightning Web Components — Engineering Standards
Component Design
- Follow single-responsibility: each component renders one cohesive piece of UI or manages one data concern.
- Decompose large components into container components (data ownership) and presentational components (display only).
- Container components wire Apex; presentational components receive data via
@apiproperties. - Never fetch data inside a presentational component.
- Keep component HTML templates free of business logic; move conditionals and transformations to the JS controller.
Reactivity and State
- Use
@trackonly when deep reactivity on nested objects is required; primitive@apiand module-level variables are automatically reactive. - Derive computed values from reactive properties using getters; do not store derived state as separate tracked variables.
- Reset component state explicitly in
disconnectedCallbackwhen subscriptions or listeners are registered. - Avoid mutating
@apiproperties directly from within the component; emit events to allow parents to manage state changes.
Apex Integration
- Prefer
@wireadapters for read operations; use imperative Apex calls only when triggering side effects or requiring explicit loading control. - Handle
@wiredata and error properties in the same property; always check both in the template. - Wrap imperative Apex calls in
try/catch; surface errors through a consistent error display pattern. - Pass minimal parameters to Apex; never pass entire record objects when only an ID is needed.
- Cache wire results where appropriate using
@wirecache support; avoid redundant re-fetches.
Events and Communication
- Use custom events for child-to-parent communication; use
@apimethods or properties for parent-to-child. - Prefer Lightning Message Service (LMS) for cross-tree communication; avoid DOM event bubbling across slot boundaries.
- Name events using lowercase kebab-case (
record-selected,form-submitted); prefix with component name if broad scope. - Always call
event.stopPropagation()when an event should not bubble beyond the current component boundary.
Security
- Never construct dynamic SOQL from LWC; delegate query logic to server-side Apex with validated inputs.
- Sanitise any dynamic HTML rendering; never use
lwc:dom="manual"with untrusted content. - Use
@AuraEnabled(cacheable=true)only on read-only Apex methods; exclude it from any method that performs DML. - Apply user permissions validation server-side; do not rely on UI element visibility for security enforcement.
Performance
- Lazy-load data-heavy child components using conditional rendering (
if:true) tied to user interactions. - Avoid querying the DOM directly (
this.template.querySelector) in loops; cache element references. - Debounce search and input handlers; avoid issuing an Apex call on every keystroke.
- Use
wirecaching and avoid repeated server calls for static or infrequently changing data.
Testing
- Write Jest unit tests for all LWC components using
@salesforce/sfdx-lwc-jest. - Mock Apex wire adapters and imperative calls using
@salesforce/apexmock utilities. - Test component rendering, event emission, and Apex error states as separate test cases.
- Do not test framework internals; test observable component behaviour from the outside.