JavaScript in LWC: The Basics · Lesson 1 of 25
How JavaScript Works in Lightning Web Components
If you come from Apex, Visualforce or Aura, the first surprise in LWC is how little "framework" there is. A Lightning Web Component is mostly plain, modern JavaScript: an ES module that exports a class. The template binds to that class's properties, and the browser does the rest using web standards. That is good news – every hour you spend getting better at JavaScript makes you a better LWC developer.
This course teaches exactly the JavaScript you meet inside components, with every example written as LWC code or as a small script you can run here. If you need a general introduction to the language first, our JavaScript course starts from zero.
In this lesson
- What the .js file of a component actually is
- Why templates push all logic into JavaScript
- The lifecycle hooks, in the order they run
- The JavaScript you need for LWC – a map of this course
A component is a module that exports a class
<!-- greetingCard.html -->
<template>
<lightning-card title="Welcome">
<p class="slds-p-horizontal_small">{greeting}, {firstName}!</p>
<p class="slds-p-horizontal_small">You have {openTasks} open {taskLabel}.</p>
</lightning-card>
</template>
// greetingCard.js
import { LightningElement } from 'lwc';
export default class GreetingCard extends LightningElement {
firstName = 'Asha'; // class fields: the component's state
openTasks = 1;
get greeting() { // a getter: computed every time the template renders
const hour = 9; // fixed here so the example is repeatable; normally new Date().getHours()
return hour < 12 ? 'Good morning' : 'Good afternoon';
}
get taskLabel() {
return this.openTasks === 1 ? 'task' : 'tasks';
}
}
▌Welcome Good morning, Asha! You have 1 open task.
Read that JavaScript file line by line and you'll find only standard language features:
import { LightningElement } from 'lwc'– an ES module import. Every component is a module; it can import other modules, Apex methods and labels.export default class GreetingCard extends LightningElement– a class that inherits from the LWC base class. The engine creates one instance per component on the page.firstName = 'Asha'– a class field. Fields are reactive: assign a new value and the template re-renders.get greeting()– a getter, which the template reads like a property.
Templates have no expressions – JavaScript does the thinking
In an LWC template you can write {firstName} or {account.Name}, but not {openTasks + 1}, {isAdmin && isActive} or {name.toUpperCase()}. This is deliberate: it keeps templates simple and fast and puts every decision in code you can test. In practice it means you write a lot of small getters, and you need to be comfortable with operators, string methods and array methods – which is exactly what the next lessons cover.
From a click to a new screen
- Eventthe user clicks; your handler method runs
- State changethe handler assigns a field: this.openTasks = 2
- Re-renderLWC notices the change and re-evaluates the template
- Getters runtaskLabel now returns "tasks"; the DOM is patched
Lifecycle hooks are just methods
The engine calls certain methods at fixed moments. You will use these four all the time:
// lifecycleDemo.js
import { LightningElement } from 'lwc';
export default class LifecycleDemo extends LightningElement {
constructor() {
super(); // always first; don't touch attributes or the DOM here
console.log('1. constructor');
}
connectedCallback() {
console.log('2. connectedCallback – inserted; load data, subscribe');
}
renderedCallback() {
console.log('3. renderedCallback – DOM is ready (runs after every render)');
}
disconnectedCallback() {
console.log('4. disconnectedCallback – removed; clean up timers and subscriptions');
}
}
<!-- lifecycleDemo.html -->
<template>
<p>Lifecycle demo</p>
</template>
console: 1. constructor console: 2. connectedCallback – inserted; load data, subscribe console: 3. renderedCallback – DOM is ready (runs after every render) › component removed from the page console: 4. disconnectedCallback – removed; clean up timers and subscriptions
renderedCallback runs again after every re-render
Setting a field inside renderedCallback triggers another render, which calls renderedCallback again. Guard one-time work with a flag such as if (this.initialized) return;.
Where your JavaScript runs
The layers under your code
- Your component classfields, getters, handlers, lifecycle hooks
- LWC enginereactivity, templates, decorators (@api, @wire, @track)
- Lightning Web Securityisolates each namespace; blocks unsafe globals and eval
- The browsermodern JavaScript (ES2020+), DOM, shadow DOM, custom elements
- Your code always runs in strict mode – undeclared variables throw instead of quietly creating globals.
- You can use modern syntax freely: classes, modules, optional chaining, async/await, private fields.
- Some browser features are restricted for security – covered in the Lightning Web Security lesson.
The JavaScript you need for LWC
| Skill | Where you use it in LWC |
|---|---|
| Values, types, operators | getters, conditional rendering, handling missing fields |
Functions, this, closures | event handlers, callbacks, debounced search |
| Objects and arrays | shaping records from Apex and wire adapters for the template |
| Classes and modules | the component itself, shared utility modules |
| Promises and async/await | imperative Apex, uiRecordApi functions, Promise.all |
| DOM and events | template.querySelector, lwc:ref, CustomEvent |
| Errors and testing | user-friendly errors, Jest tests |
Practice
Try it yourself
A colleague writes
<p>{amount * 1.18}</p>to show an amount with GST, and the component fails to compile. Fix it the LWC way.Show answer
Templates can't evaluate expressions. Add a getter –
get amountWithGst() { return this.amount * 1.18; }– and bind{amountWithGst}.Which hook would you use to start a
setIntervalthat refreshes a clock, and which to stop it?Show answer
Start it in
connectedCallbackand clear it indisconnectedCallback; otherwise the timer keeps running after the component leaves the page.
Quick check
What does a component's JavaScript file export?
A default class that extends LightningElement.
Why does LWC code use so many getters?
Templates have no expressions, so any computed value is a getter on the class.
Which hook runs after every render?
renderedCallback.
Summary
- An LWC JavaScript file is an ES module exporting a class that extends LightningElement.
- Fields hold state, getters compute what the template shows, methods handle events.
- Lifecycle hooks are methods: constructor, connectedCallback, renderedCallback, disconnectedCallback.
- Strong modern JavaScript is the real skill behind good components.
Finished this lesson?
Mark it complete to track your progress, then carry on with the next lesson.