TL;DR
- Lightning Web Components is Salesforce's standards-based UI framework and the default for all new Lightning Experience UI. It's modern JavaScript plus decorators, wire adapters and base components.
- Learn it in this order: JavaScript (free course), then the LWC course for events, Lightning Data Service, Apex and messaging, then real projects to tie it together.
- LWC templates can't contain expressions. Compute everything in JavaScript getters. Getting that habit early prevents a whole class of bugs.
What the courses cover
Pulled live from the course catalogue — module by module.
- Introduction
- Events
- Lightning Data Services
- LWC & Apex
- Configuring & Exposing Web Components
- Navigation in LWC
- Coding Challenges
- Lightning Message Service
- Lightning Testing Service
- URL Shortener App
- Coding Reddit.com clone with Lightning Framework
- File Uploader
- Hacking DataTable Component
To learn Lightning Web Components, get comfortable with modern JavaScript first, then learn how a component's template binds to its class, how components talk through events, how to read and write data with Lightning Data Service and Apex, and how to expose components to Lightning pages. The courses above follow that order, from the free JavaScript course to a Reddit clone and a URL shortener in the real-projects course. Every component is built live in a real org, errors included.
What LWC is and where you use it
Lightning Web Components is Salesforce's UI framework, built on web standards: custom elements, ES modules and the shadow DOM. Each component is a folder with an HTML template, a JavaScript class and a metadata file that says where the component can be used.
On real projects, I build LWCs for:
- Record page components that show related data in a more useful shape than a related list
- Screen flow components that give flows a custom input or display
- Quick actions for focused tasks launched from a record
- Data tables with inline editing, custom cell types and row actions
- Experience Cloud pages for customers and partners
- Utility bar tools that agents keep open all day
LWC is the default for new UI. Aura still exists in many orgs, and the Aura guide explains when you still need it.
Prerequisites
- Modern JavaScript. Classes, modules, arrow functions, destructuring and promises. The free JavaScript for LWC course covers exactly that.
- The Salesforce data model and security basics. See the admin guide.
- Some Apex. Enough to write an
@AuraEnabledmethod. See Apex. - VS Code and the
sfCLI, covered in Salesforce DX and VS Code.
What you'll be able to build afterwards
- Record page components that use Lightning Data Service, with no Apex needed for simple cases
- Parent-child component trees that communicate with
@apiproperties and custom events - Components in unrelated parts of the page that talk through Lightning Message Service
- Apex-backed components using
@wireand imperative calls, with proper error handling - Navigation between records, pages and tabs with the navigation service
- Full mini-apps such as a file uploader and an extended data table
A hands-on example: a record page component with no expressions
This component shows an account's name and revenue on its record page. It uses Lightning Data Service, so there's no Apex.
<template>
<lightning-card title="Account summary" icon-name="standard:account">
<div class="slds-p-horizontal_small">
<template lwc:if={hasError}>
<p class="slds-text-color_error">{errorMessage}</p>
</template>
<template lwc:elseif={isLoaded}>
<p class="slds-text-heading_small">{name}</p>
<p>{revenueLabel}</p>
</template>
<template lwc:else>
<lightning-spinner alternative-text="Loading" size="small"></lightning-spinner>
</template>
</div>
</lightning-card>
</template>
import { LightningElement, api, wire } from 'lwc';
import { getRecord, getFieldValue } from 'lightning/uiRecordApi';
import NAME_FIELD from '@salesforce/schema/Account.Name';
import REVENUE_FIELD from '@salesforce/schema/Account.AnnualRevenue';
export default class AccountSummary extends LightningElement {
@api recordId;
account;
error;
@wire(getRecord, { recordId: '$recordId', fields: [NAME_FIELD], optionalFields: [REVENUE_FIELD] })
wiredAccount({ data, error }) {
if (data) {
this.account = data;
this.error = undefined;
} else if (error) {
this.error = error;
this.account = undefined;
}
}
get isLoaded() {
return Boolean(this.account);
}
get hasError() {
return Boolean(this.error);
}
get errorMessage() {
return this.error && this.error.body ? this.error.body.message : 'Could not load the account';
}
get name() {
return getFieldValue(this.account, NAME_FIELD);
}
get revenueLabel() {
const revenue = getFieldValue(this.account, REVENUE_FIELD);
return revenue ? `Annual revenue: ${revenue.toLocaleString()}` : 'No annual revenue recorded';
}
}
Why it's built this way:
- The template has no expressions. Every binding, including
{hasError},{isLoaded}and{revenueLabel}, is a getter or a property. The formatting logic lives in JavaScript, where you can read and test it. More in LWC templates: no expressions, use getters. lwc:if,lwc:elseifandlwc:elsereplace the olderif:directives and make the three states explicit: error, loaded and loading.- Fields are imported from
@salesforce/schema. Salesforce knows the component depends on those fields, so an admin can't delete one that's in use, and a typo fails at deploy time instead of at runtime. '$recordId'is reactive. The$prefix tells the wire adapter to re-run whenrecordIdchanges. Without it, you'd pass the literal string.- Annual revenue is an optional field. With
fields, the whole wire fails if the user can't see a field. WithoptionalFields, that field is simply left out.
To place it on a page, expose the component in its metadata file with the lightning__RecordPage target.
How components talk to each other
Most LWC confusion after the basics is about communication, so it's worth having the rules straight before you build anything bigger:
- Parent to child: the parent sets a public
@apiproperty on the child, or calls a public@apimethod. - Child to parent: the child dispatches a
CustomEventand the parent handles it with anonhandler in its template. Data goes in the event'sdetail. - Unrelated components on the same page: publish and subscribe through a Lightning Message Service channel. That also works across LWC, Aura and Visualforce.
- Record changes: if two components show the same record through Lightning Data Service, they stay in sync automatically. After an Apex update, notify LDS so cached records refresh.
Getting this wrong usually shows up as a child component changing data it doesn't own. Data goes down, events go up.
Common mistakes beginners make
- Expressions in templates.
{items.length === 0}won't compile. Use a getter such as{isEmpty}. - Using the deprecated
if:directives in new code instead oflwc:if,lwc:elseifandlwc:else. - Forgetting the
$in wire parameters, so the wire never reacts to the property changing. - Calling Apex for everything. For single-record reads and writes, Lightning Data Service is faster, cached and respects security for you.
- Changing an
@apiproperty from inside the child. Data flows down. Fire an event and let the parent own the change. - Bad event names. Use lowercase names with no
onprefix, such asselect, and document what's indetail. - Querying the DOM too early.
this.template.querySelectorreturns nothing in the constructor. Use it after render. - Ignoring the error branch of a wire, which leaves users staring at a spinner forever.
How LWC connects to the other topics
- It starts with JavaScript for LWC, the free prerequisite course.
- It depends on Apex for server logic, and on Apex testing for testing that logic.
- LWCs can run inside screen flows, so Salesforce Flows and LWC often meet on the same project.
- If you maintain older UI, the Aura guide explains how the two frameworks coexist.
- For interviews, practise LWC interview questions. For the overall path, see the Salesforce developer roadmap.
Who should skip this
- Skip it if you only configure and automate, and never plan to build UI. Flow screens and Dynamic Forms cover a lot of ground.
- Skip the core course if you already ship LWCs with LDS, wire adapters and messaging. The real-projects course may still be worth your time.
- Don't skip the JavaScript course if you're coming from Visualforce or Aura. Most LWC confusion is really JavaScript confusion.
The JavaScript course is free, so start there and judge the teaching before you subscribe. There are no refunds.
Javascript for Lightning Web Components [FREE]
22 episodes · 2.6 hours
Lightning Web Components Development
58 episodes · 7.9 hours · 9 modules
Build Real Projects with Lightning
21 episodes · 3.5 hours · 4 modules
Learn it by building it
Every course, every code repository, the discussion group and certificates of completion — one subscription.
Frequently asked questions
How long does it take to learn LWC?
If your JavaScript is solid and you know the Salesforce data model, you can build simple record-page components quickly. Being comfortable with events, wire adapters, Lightning Data Service and Apex together takes a few months of real building.
Should I learn Aura or LWC?
LWC. It's the default for new Salesforce UI. Learn Aura only if you maintain an org that already has Aura components.
Do I need Apex to build Lightning Web Components?
Not for everything. Lightning Data Service handles single-record reads and writes without Apex. You need Apex for complex queries, aggregations, multi-object saves and callouts.
Why can't I use expressions in LWC templates?
LWC templates only bind to properties and getters; they don't evaluate expressions like comparisons or method calls. Move the logic into a getter in the JavaScript class and bind the getter.
Are the old if: template directives still supported in LWC?
The legacy if: directives still work in existing code but are no longer recommended. Use lwc:if, lwc:elseif and lwc:else for new components.
Keep going
Topic guide
Learn JavaScript for LWC: The Modern JS You Need Before Lightning Web Components
Interview questions
LWC Interview Questions and Answers (2026)
Blog
Why LWC Templates Don't Allow Expressions, and the Getter Pattern That Fixes It
Career roadmap
Salesforce Developer Roadmap 2026
Topic guide
Learn Apex: A Hands-On Salesforce Apex Course for Developers
Blog
Learn JavaScript Before LWC: The 12 Concepts That Matter