Developer 📅 August 2024  •  ⌛ 8 min read

Building Your First Lightning Web Component: A Step-by-Step Tutorial

LWC is the modern way to build UIs in Salesforce. Here is everything you need to create, wire up, and deploy your first component.

What Is an LWC?

Lightning Web Components (LWC) is Salesforce's modern UI framework based on web standards — custom elements, shadow DOM, and ES6+ JavaScript. Unlike Visualforce (server-rendered) or Aura Components (proprietary), LWC runs natively in the browser and is fast, lightweight, and aligned with how modern JavaScript development works.

Component Structure

Every LWC lives in its own folder and has three core files:

  • myComponent.html — the template, wrapped in a <template> tag
  • myComponent.js — the controller class extending LightningElement
  • myComponent.js-meta.xml — metadata defining where the component can be used (App Page, Record Page, etc.)

Optional: myComponent.css for scoped styles (automatically applied to this component only).

Key Decorators

@api — marks a property or method as public. Parent components pass data in via @api properties. These are reactive — the template re-renders when the value changes.

@track — marks a private property as reactive. In modern LWC, @track is rarely needed because all class fields are already reactive at the top level. You only need it for deep object mutations.

@wire — declaratively calls a Salesforce wire adapter (such as getRecord or a custom Apex method annotated with @AuraEnabled(cacheable=true)) and automatically provides the result to the template.

Event Communication

Child-to-parent: the child fires a custom event with this.dispatchEvent(new CustomEvent('myevent', { detail: data })). The parent listens with onmyevent={handleEvent} in the template.

Parent-to-child: the parent passes data via an @api property on the child, or calls a public method on the child using a template ref.

Calling Apex from LWC

Import the method: import getContacts from '@salesforce/apex/ContactController.getContacts'; then wire it: @wire(getContacts, { accountId: '$accountId' }) contacts;. For imperative calls (when you need to call it conditionally), use it as a promise in a JavaScript method.

Deploying Your Component

Use VS Code with the Salesforce Extension Pack. Run SFDX: Deploy Source to Org on the component folder, or use the CLI: sf project deploy start --source-dir force-app/main/default/lwc/myComponent. Then add it to a page in Lightning App Builder and activate.

JavaScript Developer Q&As → ← Back to Blog