Introduction
When building complex Lightning Web Components (LWC) in Salesforce, developers often need to facilitate communication between components that aren’t in a direct parent-child relationship. Two primary approaches for this are Lightning Message Service (LMS) and the Publish-Subscribe (Pub-Sub) pattern. While they might seem similar at first glance, they have distinct characteristics, use cases, and implementations.
In this blog post, we’ll dive deep into both communication methods, compare their features, and provide practical examples to help you understand when to use each one.
What is Component Communication in LWC ?
Before comparing LMS and Pub-Sub, it’s essential to understand why we need these communication patterns in the first place. In LWC architecture:
Parent-to-child communication is straightforward using public properties (
@api
)Child-to-parent communication uses events
For components that aren’t directly related or are in different DOM trees (like components in different parts of a single page app), we need more sophisticated communication patterns – which is where LMS and Pub-Sub come in.
1. Lightning Message Service (LMS)
What It Is
Lightning Message Service (LMS) is a Salesforce-native service that enables communication between Visualforce pages, Aura components, and Lightning web components across different DOM contexts.
It uses the Salesforce Lightning Message Channel to facilitate this communication.
Key Features
- âś…Â Supported by Salesforce (officially documented & maintained)
- âś… Supported Across Technologies: Works between LWC, Aura, and Visualforce
- âś…Â Works across DOM & shadow boundaries (even between different frameworks)
- âś… Requires Message Channels: Defined in XML files
- âś…Â Requires no custom JavaScript (usesÂ
<lightning-message-service>
) - ✅ Secure & scalable (managed by Salesforce platform)
When to Use LMS
Communication between LWC ↔ Aura ↔ Visualforce
When you need Salesforce-supported solutions
For cross-tab communication (using EMP API alongside LMS)
Example Implementation
1. Create a Message Channel
First, define a message channel in an XML file:
Notification Channel
Channel for sending notifications
true
message
The notification message
2. Publish a Message (LWC)
// publisher.js
import { LightningElement, wire } from 'lwc';
import { publish, MessageContext } from 'lightning/messageService';
import NOTIFICATION_CHANNEL from '@salesforce/messageChannel/notificationChannel__c';
export default class PublisherComponent extends LightningElement {
@wire(MessageContext) messageContext;
handlePublish() {
const payload = {
message: 'Hello from Publisher!'
};
publish(this.messageContext, NOTIFICATION_CHANNEL, payload);
}
}
3. Subscribe to a Message (LWC)
// subscriber.js
import { LightningElement, wire } from 'lwc';
import { subscribe, MessageContext } from 'lightning/messageService';
import NOTIFICATION_CHANNEL from '@salesforce/messageChannel/notificationChannel__c';
export default class SubscriberComponent extends LightningElement {
receivedMessage;
@wire(MessageContext) messageContext;
connectedCallback() {
this.subscription = subscribe(
this.messageContext,
NOTIFICATION_CHANNEL,
(message) => this.handleMessage(message)
);
}
handleMessage(message) {
this.receivedMessage = message.message;
}
disconnectedCallback() {
unsubscribe(this.subscription);
}
}
2. Pub-Sub (Publish-Subscribe) Pattern
What It Is
- The Pub-Sub pattern is a more generic JavaScript design pattern where publishers send messages without knowledge of subscribers, and subscribers receive messages without knowledge of publishers.
- In LWC, we often implement a custom Pub-Sub pattern using a shared JavaScript module.
Works only within LWC (not Aura or Visualforce).
Key Features
- âś…Â Lightweight & flexible (no metadata setup required)
- âś…Â Works purely in JavaScript (noÂ
.messageChannel
files) - ❌ Limited to LWC (Works only between Lightning Web Components)
- ❌ No Cross-Technology Support : Does not work with Aura or Visualforce.
- ❌ Manual cleanup required (risk of memory leaks)
When to Use Pub-Sub
For LWC-to-LWC communication only
When you need a quick, custom solution
If you don’t need Salesforce-managed messaging
Example Implementation
1. Create a Pub-Sub Utility (pubsub.js)
// pubsub.js
const callbacks = {};
const register = (eventName, callback) => {
if (!callbacks[eventName]) {
callbacks[eventName] = new Set();
}
callbacks[eventName].add(callback);
};
const unregister = (eventName, callback) => {
if (callbacks[eventName]) {
callbacks[eventName].delete(callback);
}
};
const fire = (eventName, payload) => {
if (callbacks[eventName]) {
callbacks[eventName].forEach(callback => {
try {
callback(payload);
} catch (error) {
console.error(error);
}
});
}
};
export { register, unregister, fire };
2. Publish an Event (LWC)
// publisher.js
import { LightningElement } from 'lwc';
import { fire } from 'c/pubsub';
export default class PublisherComponent extends LightningElement {
handlePublish() {
fire('notification', { message: 'Hello from Publisher!' });
}
}
3. Subscribe to an Event (LWC)
// subscriber.js
import { LightningElement } from 'lwc';
import { register, unregister } from 'c/pubsub';
export default class SubscriberComponent extends LightningElement {
receivedMessage;
connectedCallback() {
register('notification', this.handleMessage.bind(this));
}
handleMessage(message) {
this.receivedMessage = message.message;
}
disconnectedCallback() {
unregister('notification', this.handleMessage.bind(this));
}
}
Comparison Table: LMS vs. Pub-Sub
Feature | Lightning Message Service (LMS) | Pub-Sub Pattern |
---|---|---|
Supported by Salesforce | ✅ Yes | ❌ No (custom code) |
Works in Aura/LWC/Visualforce | ✅ Yes | ❌ LWC only |
Requires Metadata Setup | ✅ (.messageChannel  file) | ❌ No |
Cross-Tab Communication | ✅ (with EMP API ) | ❌ No |
Memory Leak Risk | ❌ No (managed by SF) | ✅ Yes (manual cleanup) |
Best For | Enterprise apps, cross-framework | Quick LWC-only solutions |
Which One Should You Use?
Use Lightning Message Service (LMS) when:
- You need communication between LWC, Aura, and Visualforce components
- You want a Salesforce-managed solution with built-in governance
- You need fine-grained control over message scope (application, page, or component)
- You’re working in a complex org where standardization is important.
Use Pub-Sub Pattern when:
- You only need communication between LWCs
- You want a lightweight solution without metadata dependencies
- You need a quick implementation for prototyping
- You want full control over the implementation details
- You’re working in a smaller org or specific app where cross-technology communication isn’t needed
Advanced Example: Combining Both Patterns
Sometimes, you might want to use both patterns in different parts of your application. Here’s how they can coexist:
// communicationService.js
import { publish, MessageContext } from 'lightning/messageService';
import { fire } from './pubsub';
// For LMS communication
export const sendLMSEvent = (messageContext, channel, payload) => {
publish(messageContext, channel, payload);
};
// For Pub-Sub communication
export const sendPubSubEvent = (eventName, payload) => {
fire(eventName, payload);
};
Performance Considerations
LMSÂ has a slight overhead as it’s a platform service with additional features
Pub-Sub is generally faster for LWC-to-LWC communication but lacks advanced features
Both patterns can lead to memory leaks if subscriptions aren’t properly cleaned up
For high-frequency messaging, Pub-Sub might be more efficient
Best Practices
For LMS:
Always unsubscribe in disconnectedCallback.
Use descriptive names for your message channels.
Consider message scope carefully (application vs. page vs. component).
Document your message channels and their expected payloads.
For Pub-Sub:
Implement proper error handling in your utility.
Clean up all subscriptions when components are destroyed.
Consider adding type checking for payloads.
Use namespacing for event names to avoid collisions.
Common Pitfalls
Memory Leaks: Forgetting to unsubscribe can lead to memory leaks.
Event Name Collisions: Using generic event names that might conflict.
Overuse: Using these patterns when simple parent-child communication would suffice.
Payload Size: Sending large payloads that impact performance.
Conclusion
While Lightning Message Service and the Pub-Sub pattern both solve similar problems of component communication in LWC, they are not the same.
LMS is a robust, Salesforce-managed solution that works across different technologies, while Pub-Sub is a lighter, JavaScript-only pattern for LWC-to-LWC communication.
Choose LMS when you need:
Cross-technology communication
Enterprise-grade governance
Advanced scoping features
Choose Pub-Sub when you need:
Quick LWC-to-LWC communication
A lightweight solution
Full control over implementation
Understanding both patterns will make you a more versatile Salesforce developer, allowing you to choose the right tool for each specific communication challenge in your Lightning Web Components.