Building a Lightning Web Component starts in a Salesforce DX project with a scratch org or sandbox. The Salesforce CLI scaffolds the component bundle, you write the HTML, JS, and metadata, deploy with sf project deploy start, and surface the component in the App Builder.
- Create a Salesforce DX project
Install the Salesforce CLI, then run sf project generate to scaffold a project. Authorize the target org with sf org login web. This sets up the folder structure expected by LWC: force-app/main/default/lwc.
- Generate the component bundle
Run sf lightning generate component --type lwc --name myComponent. The CLI creates the four-file bundle: HTML template, JS class, meta XML, and an empty CSS file. The bundle goes into force-app/main/default/lwc/myComponent.
- Mark the metadata so the component surfaces in App Builder
Open myComponent.js-meta.xml and set isExposed to true. Add the lightning__RecordPage, lightning__AppPage, or lightning__HomePage targets depending on where the component should appear. Without this metadata, the component compiles but never shows up in the Builder palette.
- Write the template and class
Edit myComponent.html with the markup. Use lwc:if, lwc:elseif, and lwc:for directives for conditional and list rendering. Edit myComponent.js to extend LightningElement, add reactive properties with @api or default reactivity, and import wire adapters or imperative Apex.
- Deploy to the org
Run sf project deploy start --source-dir force-app/main/default/lwc/myComponent. The CLI compiles, validates, and pushes the component. Deployment errors surface as compile errors or metadata mismatches, both readable in the CLI output.
- Drop the component on a Lightning page
Open Setup, Lightning App Builder, edit a record page, drag the component from the Custom palette, save, and activate. The component now renders for every user with access to the page.
Boolean flag in the meta XML that decides whether the component is visible in App Builder. Set to true for any component intended for declarative use.
List of contexts where the component can run: lightning__RecordPage, lightning__AppPage, lightning__HomePage, lightningCommunity__Page, lightning__FlowScreen, and others.
Declares which Salesforce API version the component targets. Older API versions follow the legacy reactivity rules, newer versions assume native shadow and the modern decorators behavior.
Per-org setting in Session Settings that enables the modern security sandbox, replacing the legacy Locker Service for namespaces opted in.
Set @AuraEnabled(cacheable=true) on Apex methods used in @wire. Without it, the wire adapter falls back to imperative semantics and loses cache benefits.
- @api properties are public. Renaming an @api property is a breaking change for every parent that consumes it. Treat @api as a contract.
- Wire adapters do not call .catch like a promise. Errors arrive as the error property of the wire result. Forgetting this leads to silently swallowed exceptions.
- Lightning Data Service caches by record ID and field list. Two components asking for different field subsets of the same record cause two cache entries, not one.
- Native shadow blocks global CSS, including SLDS overrides. If your design system tokens are not appearing inside an LWC, you are probably running native shadow and need to import the styles via the lightning-stylesheet pattern.
- Lightning Web Security is not a drop-in replacement for Locker. Test third-party JavaScript libraries in a sandbox before flipping LWS on at the org level.