Compatibility and runtime
Browser support
The supported desktop policy is the current and previous stable releases of Chromium, Firefox, and Safari. The mobile policy covers current Chrome on Android and Safari on iOS, with targeted Firefox for Android validation for select and combobox behavior.
CI runs the complete component suite in Chromium, Firefox, and WebKit. WebKit is the available cross-platform Safari engine check; release-critical mobile and assistive-technology behaviors still require the manual matrix in Accessibility testing.
Components feature-detect optional platform APIs and preserve a usable native path when an enhancement is unavailable. “Supported” therefore has two levels:
- Progressive baseline: meaningful native markup, form submission, label association, and ordinary links or controls remain available before upgrade or without JavaScript.
- Full enhancement: the custom element has upgraded and its richer popup, keyboard, focus, styling, or layout behavior is active in a supported browser.
Component pages document narrower platform caveats. In particular, read the
mobile notes for rc-select and
rc-combobox before choosing a popup mode.
Server rendering
Every package entry point imports in Node without a DOM: Lit's server build
supplies the HTMLElement and customElements shims, and no package touches
document or window while its module evaluates. The CI build checks every
entry point this way. A framework that evaluates client modules during a server
render, such as a React client component, can therefore import the packages.
Calling a define entry on the server registers the element with the shim and
has no other effect.
Rendering components on the server is a separate contract. The supported path is native fallback markup from the server, with the elements upgrading once the client loads their definitions. Every element also renders with Lit's server renderer, including declarative shadow roots, and hydrates that output; CI checks both for every element. The server rendering guide covers the stylesheets that keep the native markup laid out before upgrade, and the current state of Lit server rendering.
Register components in a client entry point:
<rc-select>
<select name="status" aria-label="Status">
<option>Draft</option>
<option>Published</option>
</select>
</rc-select>
// Client-only entry point
import '@rcarls/rc-webcomponents/rc-select/define';
Frameworks that evaluate route modules on the server should place registration behind their documented client-only boundary. The native child remains useful until the browser loads and upgrades the custom element; this is progressive enhancement, not component hydration.
Import choice
Prefer the aggregate package's per-component subpaths. They keep dependency management centralized without pulling unused components into the bundle:
import '@rcarls/rc-webcomponents/rc-button/define';
import '@rcarls/rc-webcomponents/rc-select/define';
Use @rcarls/rc-webcomponents/define only when the application genuinely wants
to register the entire collection. Likewise, import classes from component
subpaths such as @rcarls/rc-webcomponents/rc-select instead of the root class
barrel when bundle size matters. See Performance for measured
sizes.
Versioning
The collection is pre-1.0. Minor releases can contain intentional breaking API
changes, which are described by Changesets and release notes. Package versions
are locked together, so use one version across all @rcarls/* packages and
review migration notes before upgrading.