Skip to main content
New tool CRON Expression Builder — preview next run times before you schedule Apex. Open the builder →
Diagram showing multiple Salesforce components communicating using the Lightning Message Service channel
Lightning

Lightning Message Service: How to Sync Salesforce Components

Tired of messy event bubbling? Lightning Message Service lets your components talk to each other even when they aren't related, which is how you sync LWC, Aura, and Visualforce on a single page.

The short answer

Lightning Message Service is the standard publish-subscribe framework for passing data between unrelated Lightning web components, Aura components, and Visualforce pages. Components sync with each other through central message channels defined in metadata.

Key takeaways Create a message channel definition in the messageChannels metadata directory before you publish or subscribe to anything. Use @api properties for parent-to-child data and custom events for child-to-parent data instead of Lightning Message Service. Keep message payloads light by sending record IDs or status flags instead of large data structures. Stay on the default page scope so messages do not leak between apps in the navigation bar. Track your component subscriptions and clean them up, or you end up with memory leaks and duplicate handlers.

Why Lightning Message Service is a total lifesaver

If you have ever struggled to get different parts of a page to talk to each other, you need to know about Lightning Message Service. It is the standard way to handle communication across the Lightning Platform without pulling your hair out. Before this came along, we relied on messy custom pub-sub implementations or complex event bubbling that usually broke the moment someone touched the code.

Lightning Message Service lets your components talk to each other even when they aren't related. Lightning Web Components (LWC), Aura, and even old-school Visualforce pages all play nicely together in one sandbox. It is built for those times when a user clicks a button in one sidebar and you need a totally separate chart component to refresh instantly.

I've seen teams spend weeks trying to sync up data across a complex console app. Honestly, most teams get this wrong by over-complicating their LWC component communication. If you find yourself passing events through five levels of parent-child components, stop. That is when you reach for a message channel instead.

An architectural diagram of several software components connected to one central communication channel.

An architectural diagram of several software components connected to one central communication channel.

How to use Lightning Message Service in your project

The whole thing works on one idea: a central channel. Think of it like a radio station. One component broadcasts a signal, and anyone tuned into that frequency hears it and decides what to do. The workflow is the same every time.

1. Create the message channel

Everything starts with a metadata file. You create an XML file in your messageChannels folder, and it defines what your "radio station" is called and what kind of data it carries:

<LightningMessageChannel xmlns="http://soap.sforce.com/2006/04/metadata">
    <masterLabel>RecordSelected</masterLabel>
    <isExposed>true</isExposed>
    <description>This channel sends record IDs across the page.</description>
    <lightningMessageFields>
        <fieldName>recordId</fieldName>
        <description>The ID of the record that was clicked.</description>
    </lightningMessageFields>
</LightningMessageChannel>

2. Publishing a message

Say you have a list of records. When a user clicks one, you want to tell the rest of the page about it. In your LWC you import the publish function and your channel. It reads more simply than it sounds.

import { LightningElement, wire } from 'lwc';
import { publish, MessageContext } from 'lightning/messageService';
import RECORD_SELECTED_CHANNEL from '@salesforce/messageChannel/RecordSelected__c';

export default class MyPublisher extends LightningElement {
    @wire(MessageContext)
    messageContext;

    handleSelect(event) {
        const payload = { recordId: event.target.dataset.id };
        publish(this.messageContext, RECORD_SELECTED_CHANNEL, payload);
    }
}

3. Subscribing to the channel

On the other side sits your listener, waiting for that channel to send something. One thing that trips people up is forgetting to clean up their subscriptions. Ignore the lifecycle and you can end up with memory leaks or weird duplicate behavior.

import { LightningElement, wire } from 'lwc';
import { subscribe, MessageContext } from 'lightning/messageService';
import RECORD_SELECTED_CHANNEL from '@salesforce/messageChannel/RecordSelected__c';

export default class MySubscriber extends LightningElement {
    subscription = null;

    @wire(MessageContext)
    messageContext;

    connectedCallback() {
        this.subscribeToMessageChannel();
    }

    subscribeToMessageChannel() {
        if (!this.subscription) {
            this.subscription = subscribe(
                this.messageContext,
                RECORD_SELECTED_CHANNEL,
                (message) => this.handleMessage(message)
            );
        }
    }

    handleMessage(message) {
        console.log('Got the ID:', message.recordId);
    }
}

When to avoid Lightning Message Service

Having a hammer doesn't make everything a nail. I've seen developers use Lightning Message Service for every single interaction on a page, and it becomes a nightmare to debug. You lose the clear data flow that makes LWC good in the first place.

If you are sending data from a parent to its direct child, use @api properties. If a child needs to talk to its direct parent, use custom events. Save LMS for components that are truly "strangers" on the page. And don't send massive data blobs or entire lists of records. Keep your payloads light: usually an ID or a simple status string is enough.

Pro tip: Always use the default page scope unless you really need a message to persist when a user switches between different apps in the Navigation Bar. Application scope can cause unexpected side effects if you aren't careful.

If you're preparing for a senior Salesforce developer interview, expect to get asked about these trade-offs. Knowing when not to use a tool is often more important than knowing how to use it.

Key takeaways

  • Use LMS for cross-framework communication (LWC to Aura or Visualforce).
  • Keep your message payloads small and focused on IDs or simple flags.
  • Always import MessageContext to keep your components testable.
  • Remember to unsubscribe if you are manually handling the subscription lifecycle.
  • Stick to page scope by default to keep your messages isolated and predictable.

Lightning Message Service makes your life as a developer much easier once you get the hang of it. It cleans up your architecture and makes your components way more modular. If you haven't tried it yet, go create a simple message channel in your scratch org and see how much cleaner your code feels. It beats the old pub-sub hacks every single time.

Frequently asked questions

When should you use Lightning Message Service instead of custom events?

Use Lightning Message Service when components are unrelated strangers on a page, or when they have to talk across LWC, Aura, and Visualforce. A direct parent and child should stick to @api properties down and custom events up.

How do you define a Lightning Message Channel?

Create an XML file in your project's messageChannels folder holding the LightningMessageChannel definition, set isExposed to true, and list the individual lightningMessageFields.

What data should you pass in a Lightning Message Service payload?

Keep payloads light. Send simple data such as a record ID or a status string instead of full record lists or heavy data blobs.

Why should you use page scope instead of application scope in LMS?

Page scope keeps messages isolated and predictable. Application scope can cause unintended side effects when users switch between different applications in the navigation bar.

Newsletter

One email every Tuesday

New guides, tool updates, and the release-note changes that break things.

No spam. Unsubscribe in one click.

Comments

Loading comments...

Leave a Comment