Give Modern Look to Your Experience Sites with custom LWR Component Library

Telegram logo Join our Telegram Channel
Give Modern Look to Your Experience Sites with custom LWR Component Library


I’ve been working with Lightning Web Components since their early days. It’s a well-designed framework that aligns closely with web standards, has a clear mental model, and integrates deeply with the Salesforce platform.

As projects grow, especially when LWC is used for Experience Sites, some practical limitations start to surface. These are not flaws in the framework, but trade-offs that become visible when components designed primarily for data-driven applications are used in design-heavy, public-facing sites.

Some recurring challenges I’ve seen:

  • Latency when loading component-heavy pages

  • Limited styling flexibility due to closed components

  • Shadow DOM boundaries making global theming difficult

  • Rebuilding common UI patterns using native elements and SLDS

  • Experience Sites slowly converging toward a similar look and feel

Individually, none of these are deal-breakers. Together, they raise a question:

What if we treated LWC not just as a framework for consuming components, but as a foundation for building our own design system?

This article explores how a lightweight, primitive-first LWR component library can help regain control over performance, customization, and visual identity, without stepping away from the Salesforce platform.


What I Built and How

Instead of creating another opinionated UI component set, I approached the problem from a lower level.

The repository contains a primitive-first LWR component library, intended to act as a foundation rather than a finished design system. The goal is not to replace SLDS or Lightning Base Components, but to create a minimal, composable layer that behaves predictably in Experience Sites.


Key decisions behind the library

Primitive components over abstractions
Each component focuses on a single responsibility. Buttons, inputs, checkboxes, radios, and layout primitives expose structure and behavior, not visual decisions. Styling is intentionally shallow and overridable.

Native HTML as the baseline
Wherever possible, components wrap native elements instead of re-implementing behavior. This preserves accessibility, keyboard interaction, and browser performance while still providing a consistent API.

Styling via tokens, not hardcoded values
Visual consistency is achieved through shared design tokens rather than embedded styles. This makes global theming possible without duplicating CSS or fighting Shadow DOM boundaries.

Composition over configuration
Large prop surfaces are avoided. Components rely on composition, with slots preferred over configuration when structural flexibility is required.

LWR-first, not Lightning-first
The library is built assuming LWR deployment from the start. Asset paths, build output, and routing align with static hosting and CDN delivery rather than Salesforce runtime assumptions.


Why LWR Changes the Equation

This approach makes more sense with LWR than with traditional Lightning runtime deployments.

Lightning Web Runtime shifts Experience Sites toward static, CDN-first delivery. This has a few important consequences:

  • Components are built and served as optimized bundles

  • Styling decisions can be resolved at build time

  • Performance becomes more predictable

  • UI code is less tightly coupled to platform runtime behavior

Once LWR is treated as a static delivery platform, building a custom component foundation stops feeling like a workaround and starts feeling intentional.


Designing Primitive Components in LWC

Primitive components are intentionally small. Their role is not to solve use cases, but to provide reliable building blocks that can be composed into higher-level patterns.

A few principles guided their design:

Start from native elements
Each primitive is built around a native HTML element. The component standardizes behavior and styling hooks, not browser functionality.

Keep the API surface small
If a component needs a large number of public attributes, it is usually no longer a primitive.

Prefer slots over props
Slots allow structural flexibility without locking consumers into predefined layouts, which is especially useful in Experience Sites.

Treat styling as a contract
Primitives expose stable styling hooks through classes and tokens. They define what can be styled and where, not the final visual outcome.

Avoid business logic
Validation rules, formatting, and workflow-specific behavior live at higher layers. Primitives remain portable and reusable.

This keeps the foundation small and stable over time.


Styling, Tokens, and Working with Shadow DOM

Styling is where most custom LWC libraries either become brittle or fall back to SLDS. Shadow DOM itself is not the issue; treating it like a global CSS surface is.

The approach in this library is to work with Shadow DOM boundaries:

Tokens as the source of truth
Colors, spacing, radii, focus styles, and interaction states are defined once and consumed consistently.

Stable internal styling hooks
Each primitive exposes predictable structure and class names inside its Shadow DOM, acting as a clear contract between component and design system.

No global CSS leakage
Global styles are limited to token definitions and shared utilities that are explicitly consumed by components.

Accessibility as a baseline
Focus rings and interaction feedback are implemented using shared tokens, ensuring consistent keyboard and accessibility behavior across components.


Closing Thought

This repository is not a drop-in replacement for SLDS or Lightning Base Components. It is an exploration of how primitive-first design, LWR, and design tokens can work together to build Experience Sites that are faster, more flexible, and visually distinct.

If you’re building long-lived Experience Sites and find yourself repeatedly working around styling and composition limits, this approach may be worth exploring.

Repo: https://github.com/rahulgawale/fandryui

Live Demo: FandryUi

No comments :
Post a Comment

Hi there, comments on this site are moderated, you might need to wait until your comment is published. Spam and promotions will be deleted. Sorry for the inconvenience but we have moderated the comments for the safety of this website users. If you have any concern, or if you are not able to comment for some reason, email us at rahul@forcetrails.com