Back to insights

Lightning Web Components & State Architecture

Lightning Message Service is not application state management

JSBC Labs8 min read

A message is not a source of truth

Lightning Message Service solves an important Salesforce problem: components that do not share a direct DOM relationship can communicate through a Lightning message channel. It works across Lightning web components, Aura components and supported Visualforce contexts, including utility items and pop-out windows. That reach makes it tempting to treat the channel as a convenient global store.

The JSBC Labs position is that a message should announce something, not become the only place that something exists. Lightning Message Service distributes serialisable payloads to subscribers; it does not establish a durable, queryable or replayable source of current application state. If a component can render correctly only when it happened to receive an earlier message, the design contains a timing dependency disguised as loose coupling.

Choose communication by relationship

Components in a parent-child hierarchy already have explicit mechanisms. Properties and public methods communicate downward; DOM events communicate upward. Those paths make ownership visible in the component tree. Salesforce recommends Lightning Message Service for components that are not in the same DOM tree, where normal containment communication cannot reach.

Use the narrowest mechanism that fits. A child should not publish an application-wide message merely to tell its parent that a row was selected. A parent should not make every descendant subscribe to a shared channel when a property expresses the dependency directly. Reserve messaging for genuine peer, cross-page or cross-technology coordination. Smaller communication scope makes behaviour easier to reason about and test.

Model notifications, not snapshots

A useful message describes a completed or requested event: a customer was selected, a filter changed or a workspace action needs attention. A weak message tries to carry an entire mutable screen model. Large snapshots become stale immediately, duplicate data already available through platform APIs and encourage subscribers to interpret fields differently.

Keep payloads small, serialisable and intentional. Prefer stable identifiers, an event type, a schema version and the minimum context needed to react. Let a subscriber retrieve authoritative record data through Lightning Data Service or its state layer. Do not include secrets, unnecessary personal data, functions or component internals. The message contract should survive a component implementation change.

Default scope protects you

Salesforce limits subscriptions to the active area by default. That area includes selected navigation tabs or items and utility items. Developers can opt into `APPLICATION_SCOPE` when a subscriber must receive messages anywhere in the application. The wider option is powerful, particularly in console applications, but it should be an architectural choice rather than habitual boilerplate.

Application scope increases the number of potential publishers, listeners and inactive-looking surfaces affected by an event. A selection made in one workspace tab can update another tab whose user context is different. Document why the wider scope is required, include context such as record or workspace identifiers and make subscriber handling idempotent. If active-area scope works, keep the smaller blast radius.

Navigation changes the lifecycle

Salesforce notes that components can be cached rather than destroyed when a user navigates away. With application-scoped messaging, those components can continue publishing and receiving messages. A developer who assumes that leaving a page ends every listener can therefore create duplicate reactions, invisible updates or memory retained longer than expected.

Manage lifecycle explicitly. Store subscription references, unsubscribe when appropriate and release manually created message contexts in service modules that do not extend `LightningElement`. Make handlers safe if the same logical notification arrives twice. Test console tabs, subtabs, utilities, pop-outs and navigation back to cached pages—not only a single record page opened from a clean browser session.

Put record state behind Lightning Data Service

Salesforce provides Lightning Data Service wire adapters and imperative functions for reading and mutating platform data through UI API. LDS manages record access, security-aware data retrieval and shared client-side caching. A custom message bus should not replace those capabilities with hand-maintained copies of sObjects distributed across components.

After a record-changing action, update the authoritative record through the supported data layer and let interested components refresh or react through the appropriate LDS mechanisms. A message may announce a business event or tell an unrelated surface that attention is needed, but it should not carry the only updated record. One canonical data path prevents competing component caches from drifting apart.

Use a state manager for coordinated client state

Some state is not a Salesforce record: a multi-step workspace may contain draft choices, calculated view state and local orchestration. Salesforce's LWC guidance describes dedicated state managers whose exposed values trigger updates in consuming components. That creates a named owner for values and the logic that changes them rather than spreading state transitions across message handlers.

Define the state model, update operations and reset rules in one layer. Components should read current values on connection instead of waiting for a future message to reconstruct them. Messages can still signal discrete events to remote surfaces, but the state manager remains the queryable current view. This separation makes late subscribers, navigation and component remounting predictable.

Put navigable state in the page reference

Filters, selected views and record context sometimes need to survive refresh, bookmarking or a shared link. Lightning navigation represents pages as `PageReference` objects and supports state for applicable page types. Hiding navigable state only inside a message sequence makes the screen impossible to reproduce directly and breaks the browser's ordinary mental model.

Use page-reference state for non-sensitive values that define a restorable view, and observe `CurrentPageReference` when the component must react to changes. Do not place personal or confidential data in URL parameters. The URL should identify the view; LDS or a state manager should provide its data; Lightning Message Service should coordinate only the events that genuinely cross those boundaries.

Treat the channel as a versioned interface

A Lightning message channel is metadata, and every publisher and subscriber becomes a consumer of its payload. Renaming fields, changing meanings or reusing one generic channel for unrelated events creates the same compatibility problems as changing an API. The compiler cannot prove that every listener interprets a loosely shaped object correctly.

Give each channel a cohesive purpose and owner. Document publishers, subscribers, scope, payload examples, optional fields and security classification. Prefer additive changes and include a schema version when independent consumers evolve at different speeds. Remove retired subscribers deliberately. A channel named `GlobalMessage` with an open-ended payload is not reusable architecture; it is an unbounded dependency map.

Test order, absence and repetition

Unit tests should prove that publishers create the documented payload and subscribers produce the right outcome. Architecture tests must go further: connect a subscriber after an event, deliver the same message twice, switch tabs, navigate away and back, and open two workspaces with different records. Confirm that components still obtain current state without relying on an earlier notification.

Monitor user-visible outcomes rather than attempting to log every message. Correlate important actions across publisher, authoritative update and subscriber response, and expose a safe recovery path when one surface is stale. Lightning Message Service is excellent infrastructure for decoupled notification. Keep state in LDS, page references or an owned state manager, and the message channel remains simple enough to deserve the trust placed in it.

Official references

Continue reading