API reference
Every export of @sigx/lynx-plugin — the Rspack / Rspeedy plugin for SignalX Lynx dual-thread rendering.
The package is ESM-only with a single entry point. Everything below is reachable from @sigx/lynx-plugin:
import { pluginSigxLynx, LAYERS, applyEntry } from '@sigx/lynx-plugin';
import type { PluginSigxLynxOptions } from '@sigx/lynx-plugin';
pluginSigxLynx is the default API. LAYERS and applyEntry are low-level escapes for custom build setups.
Functions
pluginSigxLynx
Creates the Rspack / Rspeedy plugin that wires SignalX into Lynx's dual-thread (Background + Main Thread) build pipeline. This is the only export most projects use.
export function pluginSigxLynx(options?: PluginSigxLynxOptions): RsbuildPlugin
Parameters
options— optional. APluginSigxLynxOptionsobject controlling CSS selector / inheritance behavior and debug-info placement. Omit it to use the defaults.
Returns
An RsbuildPlugin — the plugin object you place in your config's plugins array. The returned plugin is named lynx:sigx and declares pre: ['lynx:rsbuild:plugin-api', 'lynx:config', 'lynx:rsbuild:dev'], so it runs after Rspeedy's own config and dev plugins.
Platform: build-time, both iOS and Android. This is not a native module; it produces the dual-thread bundles that the native runtime consumes.
// lynx.config.ts
import { defineConfig } from '@lynx-js/rspeedy';
import { pluginSigxLynx } from '@sigx/lynx-plugin';
export default defineConfig({
plugins: [pluginSigxLynx()],
});
applyEntry
Low-level helper that performs the dual-thread entry splitting directly. For each user entry it creates a <name>__main-thread entry in the main-thread layer and a <name> entry in the background layer, then registers the template-webpack-plugin to stitch them into one .lynx template. pluginSigxLynx calls this for you; reach for it only when building a custom plugin or bypassing the standard pipeline.
export declare function applyEntry(
api: RsbuildPluginAPI,
opts?: ApplyEntryOptions,
): Promise<void>
Parameters
api— theRsbuildPluginAPIhanded to a plugin'ssetupfunction.opts— optional. AnApplyEntryOptionsobject with the same CSS / debug fields asPluginSigxLynxOptions. Note that theApplyEntryOptionstype itself is not re-exported from the package root (see Types below).
Returns
A Promise<void> that resolves once the entries and template plugin are registered.
Platform: build-time, both iOS and Android.
Constants
LAYERS
Webpack module-layer name constants used to separate the dual-thread bundles — background JS versus main-thread Lepus. Use these when writing custom rules that need to target one layer.
export const LAYERS = {
BACKGROUND: 'sigx:background',
MAIN_THREAD: 'sigx:main-thread',
} as const;
Members
LAYERS.BACKGROUND—'sigx:background'. The layer for the background-thread JS bundle.LAYERS.MAIN_THREAD—'sigx:main-thread'. The layer for the main-thread (Lepus) bundle.
Platform: build-time, both iOS and Android.
Types
PluginSigxLynxOptions
Configuration options accepted by pluginSigxLynx. All fields are optional.
export interface PluginSigxLynxOptions {
/** Whether to enable CSS selector support in the Lynx template. @defaultValue true */
enableCSSSelector?: boolean;
/** Whether to enable CSS inheritance in the Lynx engine. @defaultValue false */
enableCSSInheritance?: boolean;
/** A list of additional CSS properties to inherit beyond the engine defaults. Only effective when enableCSSInheritance is true. */
customCSSInheritanceList?: string[];
/** Whether themes and safe-area may ride inline CSS custom properties (requires Lynx ≥ 3.9). @defaultValue true */
enableCSSInlineVariables?: boolean;
/** Opt into Lynx 4.0's new sticky layout for `<list>` section headers. @defaultValue false */
enableNewSticky?: boolean;
/** Register the Fiber Element API through Lynx 4.0's new raw binding path. @defaultValue false */
enableElementApiNewRegistration?: boolean;
/** Encode `@media` / `@supports` / `@layer` rules into the `.lynx` template. @defaultValue true */
enableCSSRule?: boolean;
/** Whether to place debug info outside the template bundle. @defaultValue true */
debugInfoOutside?: boolean;
}
Fields
enableCSSSelector?: boolean— enable CSS selector support in the Lynx template. Defaulttrue.enableCSSInheritance?: boolean— enable CSS inheritance in the Lynx engine. Defaultfalse.customCSSInheritanceList?: string[]— additional CSS properties to inherit beyond the engine defaults. Only effective whenenableCSSInheritanceistrue.enableCSSInlineVariables?: boolean— let themes (@sigx/lynx-zeroThemeProvider) and safe-area publish inline CSS custom properties for first-frame-perfect runtime theming. Defaulttrue; requires Lynx ≥ 3.9 on native hosts. A kill switch for hosts that can't run 3.9.enableNewSticky?: boolean— opt into Lynx 4.0's new sticky layout for<list>section headers. Defaultfalse. It changes where and when a header pins, so re-check anything doing pixel math against sticky positions.enableElementApiNewRegistration?: boolean— select Lynx 4.0's new raw binding path for the Fiber Element API. Defaultfalse. Every<sigx-*>custom element is created through the generic__CreateElement, so this switch moves the entire custom-element surface at once; opting in is a deliberate, test-it-yourself choice.enableCSSRule?: boolean— route stylesheet encoding through the tasmCSSRuleParser, the only encoder path that carries@media,@supportsand@layerrules into the.lynxbinary. Defaulttrue;falseis the kill switch that restores the pre-4.0 encoding exactly. Read at encode time, so it needs@lynx-js/template-webpack-plugin≥ 0.14 (@lynx-js/tasm≥ 0.0.41) to have any effect; when enabled the encoder also forcesenableCSSSelectorandenableCSSInvalidationon. Evaluating the rules on device needs a Lynx ≥ 4.0 host.debugInfoOutside?: boolean— place debug info outside the template bundle. Defaulttrue.
Page-config flags
The four flags above are written into the .lynx template's page config. They share one rule: the plugin always encodes the resolved boolean, never omits the key. An absent key means "whatever the engine or host decides today", which is how a behaviour change arrives without anyone choosing it. A host older than the engine version listed simply ignores the key, so encoding one is always safe.
| Flag | Needs | Default | Opt in with |
|---|---|---|---|
enableCSSInlineVariables | Lynx ≥ 3.6, and ≥ 3.9 to re-resolve on change | true | on by default; false is the kill switch |
enableNewSticky | Lynx ≥ 4.0 | false | pluginSigxLynx({ enableNewSticky: true }) |
enableElementApiNewRegistration | Lynx ≥ 4.0 | false | pluginSigxLynx({ enableElementApiNewRegistration: true }) |
enableCSSRule | tasm ≥ 0.0.41 to encode; Lynx ≥ 4.0 to evaluate | true | on by default; false is the kill switch |
enableElementApiNewRegistration is pinned for a stronger reason than the others: upstream marks it readSettings: true, so a host setting can flip it under a bundle that never asked. The page config takes precedence over settings, so encoding the boolean keeps the choice with the app.
enableCSSRule has two ways of ending up false for a bundle — the kill switch and the web target, whose encoder drops at-rules regardless — so the resolved answer is also folded into the bundle as the __SIGX_CSS_RULE__ define.
Build-time defines
The plugin folds these boolean literals into every bundle. They are declared in @sigx/lynx/client, so an app with the standard /// <reference types="@sigx/lynx/client" /> gets them typed. Because they are literals, if (__X__) { … } branches tree-shake out of the bundle they are false in.
| Define | Value |
|---|---|
__WEB__ / __NATIVE__ | which environment the bundle targets |
__MAIN_THREAD__ / __BACKGROUND__ | which thread's bundle this is |
__DEV_BUILD__ | true in a development build (NODE_ENV !== 'production'), false in a release build |
__SIGX_CSS_RULE__ | whether @media / @supports rules reach this bundle's binary — false on the web target and under enableCSSRule: false |
Use __DEV_BUILD__, not __DEV__. The bare __DEV__ expands to a process.env expression that throws in the Lynx background runtime. __DEV_BUILD__ is resolved in Node at build time, so it both works at runtime and tree-shakes out of a release bundle. Its typical use is refusing to present a measurement taken from a development build: main-thread costs there are inflated by orders of magnitude (upstream's setStyleProperty copies a 256-entry array per call under __DEV__), so any perf number from a dev build is meaningless.
if (__DEV_BUILD__) {
showBanner('DEV BUILD — NOT REAL NUMBERS');
}
__SIGX_CSS_RULE__ reflects the encoder only — it cannot know the host's engine version. Branch on it when a rule's absence would leave something unstyled rather than merely unrefined: a palette that only exists inside @media (prefers-color-scheme: …) needs a JS fallback where it is false. @sigx/lynx-zero's <ThemeProvider> reads it to choose between letting the CSS engine resolve a built-in theme's palette and declaring that palette inline.
ApplyEntryOptions
Parameter type of applyEntry. It carries the same fields as PluginSigxLynxOptions.
export interface ApplyEntryOptions {
enableCSSSelector?: boolean; // default true
enableCSSInheritance?: boolean; // default false
customCSSInheritanceList?: string[];
debugInfoOutside?: boolean; // default true
}
Note: ApplyEntryOptions is declared in the plugin's internal entry module but is not re-exported through the package root — only the applyEntry function symbol is. Consumers importing from @sigx/lynx-plugin get applyEntry but cannot name ApplyEntryOptions via the public entry. Pass an inline object literal, or use PluginSigxLynxOptions, which has the same shape.
RsbuildPlugin
Return type of pluginSigxLynx. Imported as a type from @rsbuild/core. The returned object has name: 'lynx:sigx' and pre: ['lynx:rsbuild:plugin-api', 'lynx:config', 'lynx:rsbuild:dev'].
