API reference
The complete typed surface of @sigx/lynx-cli — config helpers, the prebuild and autolink machinery, the dev server, and device detection.
The package is ESM-only and exposes two import entry points: @sigx/lynx-cli (the root barrel) and @sigx/lynx-cli/config (the config subset, identical to the config exports of the root). A third file, dist/plugin.js, is the @sigx/cli plugin — it is declared under the package's sigx-cli.plugin field and loaded by the CLI host. It is not in the exports map, so you cannot import it directly.
CLI commands
These are the real user-facing API for most apps. They are registered by the plugin and run via sigx <command>.
| Command | Key flags |
|---|---|
dev | --port <n> (8788), --host, --ios, --android, --all, --last, --variant <name>, --verbose, --no-device-logs |
build | --analyze, --variant <name> |
prebuild | --android, --ios (default both), --clean, --variant <name> |
run:android | --release, --variant <name>, --verbose |
run:ios | --release, --variant <name>, --simulator <name>, --device <name|udid>, --verbose (macOS only) |
doctor | — |
add | positional @sigx/lynx-* names, --caret, --force |
remove | positional @sigx/lynx-* names |
outdated | --tag <dist-tag> |
upgrade | --to <version|dist-tag>, --dry-run, --caret, --force |
--variant <name> (or the SIGX_VARIANT env var) selects a build variant from the variants map — see Build variants. See the Usage guide for command behavior and examples.
Config functions
defineLynxConfig
export function defineLynxConfig(config: LynxConfig): LynxConfig
Identity helper for typing the sigx-lynx project config in signalx.config.ts. Returns its argument unchanged; its only job is to give you full type-checking and editor completion. Re-exported from both the root entry and the ./config subpath.
resolveConfig
export function resolveConfig(raw: LynxConfig): ResolvedConfig
Parse a raw LynxConfig into a fully-resolved config with defaults applied and modules/iconSets normalised. Validates iconSets, throwing on a duplicate id, a missing source, or an invalid mode/style.
modulesForPlatform
export function modulesForPlatform(config: ResolvedConfig, platform: Platform): ResolvedModule[]
Filter a resolved config's modules down to those supporting the given platform.
resolveAssets
export function resolveAssets(
raw: LynxConfig,
cwd: string
): { ios: ResolvedIosAssets; android: ResolvedAndroidAssets }
Resolve all icon / splash / scheme / orientation asset paths (absolute) and per-platform overrides, falling back to bundled placeholders in templates/defaults/ when unset.
Manifest functions
validateManifest
export function validateManifest(manifest: unknown): string[]
Validate a signalx-module.json object. Returns an array of human-readable error strings; an empty array means valid. Rejects the legacy kind field and requires a config block per declared platform. (Module manifests are shipped by native @sigx/lynx-* modules, not by an app.)
Autolink functions
linkAndroid
export function linkAndroid(
config: ResolvedConfig,
manifests: ModuleManifest[]
): AndroidLinkResult
Android. Generate Android auto-link output — Kotlin registry / lifecycle / activity-hook / behavior code, Gradle deps, permissions, features, services and meta-data — for a set of module manifests.
linkIos
export function linkIos(
config: ResolvedConfig,
manifests: ModuleManifest[]
): IosLinkResult
iOS. Generate iOS auto-link output — Podfile entries, usage descriptions, background modes, BGTask identifiers, and Swift registry / lifecycle / AppDelegate-hook / component-registry code — for a set of module manifests.
Prebuild functions
runPrebuild
export async function runPrebuild(opts: PrebuildOptions = {}): Promise<void>
Orchestrate prebuild: load config + manifests, render the native ios/ and android/ projects, auto-link installed @sigx/lynx-* modules, then run the prebuild.post hook. Has a fingerprint-based fast path that skips when inputs are unchanged (bypassed by clean: true).
The PrebuildOptions type is referenced below but is not re-exported from the package entry.
loadConfig
export async function loadConfig(cwd: string): Promise<LynxConfig>
Load and evaluate signalx.config.{ts,js,mjs} from the project root (esbuild-compiled), returning the raw LynxConfig.
loadManifests
export async function loadManifests(modulePackages: string[], cwd: string): Promise<ModuleManifest[]>
Resolve and read the signalx-module.json manifests for the given package names. Handles pnpm transitive resolution and sorts lynx-core's activity hook first.
Dev server function
startDevServer
export async function startDevServer(opts: DevServerOptions): Promise<void>
Start the rspeedy dev server: probes for a free port (default 8788), prints a QR / LAN-IP banner, streams device console.* logs, and auto-launches the selected targets with the dev URL. The DevServerOptions type is referenced below but is not re-exported from the package entry.
Doctor function
runDoctor
export async function runDoctor(cwd: string, logger: Logger): Promise<void>
Print an environment health report: Node, package manager, Android SDK / JDK / ADB, iOS Xcode / CocoaPods, and connected devices. The Logger type comes from @sigx/cli and is not exported by this package.
QR function
generateQR
export function generateQR(text: string, opts?: { quiet?: number; invert?: boolean }): string
Encode a short URL into a terminal QR code rendered with Unicode half-block characters. Zero dependencies; byte mode, EC level L, versions 1-20. The default quiet zone is 4. Falls back to " [QR: <text>]" if encoding fails.
Network functions
getLanIP
export function getLanIP(): string | null
Return the primary non-internal LAN IPv4 address (real interfaces preferred over virtual), or null if none.
getAllLanIPs
export function getAllLanIPs(): { name: string; address: string }[]
Return all non-internal IPv4 interfaces, sorted so real interfaces (Wi-Fi / Ethernet) precede virtual ones (Hyper-V / WSL / Docker / etc.).
Device-detect functions
The interface types these functions return (AndroidDevice, IosSimulator, IosDevice, DeviceStatus) are defined in device-detect.ts but only the values are re-exported from the root entry — those type interfaces are not importable from @sigx/lynx-cli.
getDeviceStatus
export function getDeviceStatus(appId?: string, iosBundleId?: string): DeviceStatus
Probe connected Android devices, iOS simulators and iOS devices, and report toolchain availability plus whether sigx-lynx-go / the given app is installed.
listAndroidDevices
export function listAndroidDevices(): AndroidDevice[]
Android. List connected devices / emulators via adb devices -l. Returns an empty array if adb is unavailable.
isAdbAvailable
export function isAdbAvailable(): boolean
Android. Whether an adb binary can be resolved (probes ANDROID_HOME/platform-tools and PATH).
isLynxGoInstalled
export function isLynxGoInstalled(deviceId: string): boolean
Android. Whether the sigx-lynx-go dev client (com.sigx.lynxgo) is installed on the given Android device serial.
launchLynxGo
export function launchLynxGo(deviceId: string, url: string): boolean
Android. Launch sigx-lynx-go on a device via an am start deep link (sigx-lynx-go://open?url=...). Returns whether it succeeded.
Plugin
plugin (default export of dist/plugin.js)
export default definePlugin({
name: 'lynx',
detect: isLynxProject,
commands: {
dev, build, doctor, outdated, upgrade, add, remove,
prebuild, 'run:android', 'run:ios',
},
})
The @sigx/cli plugin, auto-discovered via the package's sigx-cli.plugin field. It registers all the sigx subcommands. It is not exported from the package's . entry — it is a separate file referenced only by the sigx-cli field and loaded by the CLI host. isLynxProject(cwd) is true when any of signalx.config.{ts,js,mjs} or lynx.config.{ts,js} exists at cwd.
Config types
LynxConfig
export interface LynxConfig {
name: string;
version?: string;
buildNumber?: string; // default '1'
icon?: string; // 1024x1024 PNG, falls back to bundled default
splash?: SplashConfig;
scheme?: string; // deep-link URL scheme
orientation?: Orientation; // default 'portrait'
modules?: (string | ModuleConfig)[]; // per-module overrides; installed modules auto-link
excludeModules?: string[];
iconSets?: IconSetConfig[];
android?: AndroidConfig;
ios?: IosConfig;
platforms?: Platform[]; // defaults to both
prebuild?: PrebuildHooksConfig;
variants?: Record<string, VariantConfig>; // per-environment app identity
}
VariantConfig
A build variant — a deep-partial of LynxConfig (override any field) plus control fields. Selected with --variant <name> (or SIGX_VARIANT); deep-merged onto the base, with the app id + display name auto-suffixed and the native project rendered into android-<name>/ / ios-<name>/. See the Build variants guide.
export interface VariantConfig extends DeepPartial<Omit<LynxConfig, 'variants'>> {
extends?: string; // inherit another variant first
idSuffix?: string; // appended to applicationId / bundleIdentifier
nameSuffix?: string; // appended to the display name
schemeSuffix?: string; // appended to the deep-link scheme
release?: boolean; // treat as a release build (default false)
iconBadge?: string | false; // launcher-icon badge label (auto for non-release)
}
The runtime accessors variant, isVariant() and isBaseBuild() (from @sigx/lynx) report the active variant in app code.
Platform
export type Platform = 'android' | 'ios';
Orientation
export type Orientation = 'portrait' | 'landscape' | 'all' | 'default';
PlistValue
A value allowed in the ios.infoPlist passthrough (and the module-manifest equivalent) — mirrors the Info.plist value types.
export type PlistValue = boolean | number | string | PlistValue[] | { [key: string]: PlistValue };
IconMode
export type IconMode = 'svg' | 'font';
IconStyle
export type IconStyle = 'solid' | 'regular' | 'brands' | 'light' | 'thin' | 'duotone';
IconSetConfig
export interface IconSetConfig {
id: string; // call-site alias, unique
source: string; // adapter npm package, e.g. '@sigx/lynx-icons-fa-free'
styles?: IconStyle[]; // FA only
mode?: IconMode; // default 'font' if adapter ships TTF else 'svg'
include?: string[]; // force-include glyphs; ['*'] ships full catalog
}
ModuleConfig
export interface ModuleConfig {
package: string; // e.g. '@sigx/lynx-camera'
platforms?: Platform[]; // omit = all
config?: Record<string, unknown>;// passed to native auto-linker
disabled?: boolean; // skip linking even though installed
}
SplashResizeMode
export type SplashResizeMode = 'contain' | 'cover' | 'center';
SplashConfig
export interface SplashConfig {
image?: string;
backgroundColor?: string; // default '#FFFFFF'
resizeMode?: SplashResizeMode; // default 'center'; iOS treats 'cover' as 'contain'
dark?: SplashDarkConfig;
}
SplashDarkConfig
export interface SplashDarkConfig {
image?: string; // falls back to light image
backgroundColor?: string; // falls back to light background
}
AdaptiveIconConfig
export interface AdaptiveIconConfig {
foreground: string; // 1024x1024, logo in inner 66% safe zone
backgroundColor?: string; // default '#FFFFFF'
monochrome?: string; // Android 13+ themed icon <monochrome> layer
}
IosIconConfig
export interface IosIconConfig {
light: string; // 1024x1024 PNG
dark?: string; // opaque recommended
tinted?: string; // grayscale source the system tints
}
AndroidFeatureConfig
export interface AndroidFeatureConfig {
name: string; // e.g. 'android.hardware.camera'
required?: boolean; // default false
}
AndroidConfig
export interface AndroidConfig {
applicationId?: string;
minSdk?: number; // default 24
targetSdk?: number; // default 35
compileSdk?: number; // default 35
versionCode?: number; // default 1
dependencies?: string[];
permissions?: string[];
features?: AndroidFeatureConfig[];
googleMapsApiKey?: string;
manifestMetaData?: Record<string, string>; // arbitrary <meta-data> entries
applicationAttributes?: Record<string, string | boolean | number>; // arbitrary <application> attrs
googleServicesFile?: string; // Firebase google-services.json, copied into android/app/ each prebuild
icon?: string;
adaptiveIcon?: AdaptiveIconConfig;
notificationIcon?: string;
notificationColor?: string;
splash?: SplashConfig;
scheme?: string;
orientation?: Orientation;
}
IosConfig
export interface IosConfig {
bundleIdentifier?: string;
deploymentTarget?: string; // default '15.0'
buildNumber?: string; // CFBundleVersion, default '1'
developmentTeam?: string; // Apple Team ID -> DEVELOPMENT_TEAM
codeSignStyle?: 'Automatic' | 'Manual';
supportsTablet?: boolean; // default true (TARGETED_DEVICE_FAMILY '1,2')
requiresFullScreen?: boolean; // default false
pods?: Record<string, string>;
usageDescriptions?: Record<string, string>;
bgTaskIdentifiers?: string[];
infoPlist?: Record<string, PlistValue>; // arbitrary Info.plist keys, merged last-write-wins
usesNonExemptEncryption?: boolean; // convenience for ITSAppUsesNonExemptEncryption
entitlements?: Record<string, PlistValue>; // app-level code-signing entitlements (counterpart to infoPlist)
icon?: string | IosIconConfig;
splash?: SplashConfig;
scheme?: string;
orientation?: Orientation;
}
PrebuildHooksConfig
export interface PrebuildHooksConfig {
// Path to a .mjs/.js/.cjs module run after managed native files are rendered
// and auto-linking is done. Default export, if a function, is awaited with
// { cwd, config, platforms }.
post?: string;
}
ResolvedConfig
export interface ResolvedConfig {
name: string;
version: string;
buildNumber: string;
modules: ResolvedModule[];
excludeModules: string[];
iconSets: ResolvedIconSet[];
platforms: Platform[];
android: Required<Pick<NonNullable<LynxConfig['android']>,
'minSdk' | 'targetSdk' | 'compileSdk' | 'versionCode'>>
& Omit<NonNullable<LynxConfig['android']>,
'minSdk' | 'targetSdk' | 'compileSdk' | 'versionCode'>;
ios: Required<Pick<NonNullable<LynxConfig['ios']>,
'deploymentTarget' | 'buildNumber'>>
& Omit<NonNullable<LynxConfig['ios']>,
'deploymentTarget' | 'buildNumber'>;
prebuild?: LynxConfig['prebuild'];
}
ResolvedModule
export interface ResolvedModule {
package: string;
platforms: Platform[];
config: Record<string, unknown>;
disabled: boolean;
}
ResolvedIconSet
export interface ResolvedIconSet {
id: string;
source: string;
styles: IconStyle[] | null;
mode: IconMode | null;
include: string[];
}
ResolvedPlatformAssets
export interface ResolvedPlatformAssets {
iconSource: string;
splashImage: string;
splashBackground: string;
splashResizeMode: SplashResizeMode;
splashDark: { image: string; backgroundColor: string } | null;
scheme: string | null;
orientation: Orientation;
}
ResolvedIosAssets
export interface ResolvedIosAssets extends ResolvedPlatformAssets {
iconDark: string | null;
iconTinted: string | null;
}
ResolvedAndroidAssets
export interface ResolvedAndroidAssets extends ResolvedPlatformAssets {
adaptiveIcon: { foreground: string; backgroundColor: string; monochrome: string | null } | null;
notificationIcon: string | null;
notificationColor: string | null;
}
Manifest types
These describe the signalx-module.json shipped by native @sigx/lynx-* modules. They are consumed by the autolinker, not authored in an app config.
ModuleManifest
export interface ModuleManifest {
name: string; // bridge name in NativeModules
package: string;
description: string;
type?: 'module' | 'dev-client';
platforms: ('android' | 'ios')[];
android?: AndroidManifest;
ios?: IosManifest;
}
AndroidManifest
export interface AndroidManifest {
moduleClass?: string;
publisherClass?: string;
activityHook?: ActivityHookManifest;
initClass?: string;
sourceDir?: string;
releaseStubsDir?: string;
debugOnly?: boolean;
dependencies?: string[];
permissions?: string[];
features?: AndroidFeatureEntry[];
gradlePlugins?: AndroidGradlePluginEntry[]; // Gradle plugins applied to app/build.gradle.kts
minSdk?: number;
services?: AndroidServiceEntry[];
behaviors?: AndroidBehaviorEntry[];
metaData?: AndroidMetaDataEntry[];
}
IosManifest
export interface IosManifest {
moduleClass?: string;
publisherClass?: string;
appDelegateHook?: IosAppDelegateHookManifest;
initClass?: string;
sourceDir?: string;
debugOnly?: boolean;
methods?: string[];
pods?: Record<string, string>;
usageDescriptions?: Record<string, string>;
backgroundModes?: string[];
bgTaskIdentifiers?: string[];
uiComponents?: IosUiComponentEntry[];
entitlements?: Record<string, PlistValue>; // code-signing entitlements aggregated into the app's .entitlements
deploymentTarget?: string;
}
AndroidMetaDataEntry
export interface AndroidMetaDataEntry {
name: string;
value?: string; // literal, highest precedence
valueFrom?: string; // dotted path into resolved config, e.g. 'android.googleMapsApiKey'
default?: string; // fallback
helpUrl?: string;
}
AndroidBehaviorEntry
export interface AndroidBehaviorEntry {
name: string; // JSX tag
behaviorClass: string; // FQ Kotlin class extending com.lynx.tasm.behavior.Behavior
}
AndroidFeatureEntry
export interface AndroidFeatureEntry {
name: string;
required?: boolean; // default false
}
AndroidGradlePluginEntry
export interface AndroidGradlePluginEntry {
id: string; // e.g. 'com.google.gms.google-services'
version: string; // e.g. '4.4.2'
requires?: string; // app-supplied config that must resolve first, e.g. 'android.googleServicesFile'
}
A Gradle plugin a module contributes to the app's plugins {} block on prebuild. A plugin with requires is applied only once that config resolves — @sigx/lynx-notifications declares com.google.gms.google-services with requires: 'android.googleServicesFile', so the plugin is skipped (and the build still succeeds) until you configure Firebase.
AndroidServiceEntry
export interface AndroidServiceEntry {
name: string; // FQ service class
exported?: boolean; // default false
actions?: string[]; // each becomes one intent-filter action
}
AndroidActivityHookMethod
export type AndroidActivityHookMethod =
| 'onCreate' | 'onResume' | 'onPause'
| 'onNewIntent' | 'onBackPressed' | 'onRequestPermissionsResult';
ActivityHookManifest
export interface ActivityHookManifest {
class: string; // FQ Kotlin object (singleton)
methods: AndroidActivityHookMethod[];
}
IosUiComponentEntry
export interface IosUiComponentEntry {
name: string; // JSX tag
uiClass: string; // Swift class extending LynxUI<UIView>
}
IosAppDelegateHookMethod
export type IosAppDelegateHookMethod =
| 'didFinishLaunching' | 'openURL' | 'continueUserActivity'
| 'didRegisterForRemoteNotificationsWithDeviceToken'
| 'didFailToRegisterForRemoteNotificationsWithError';
IosAppDelegateHookManifest
export interface IosAppDelegateHookManifest {
class: string; // Swift class/enum name
methods: IosAppDelegateHookMethod[];
}
Autolink result types
AndroidLinkResult and IosLinkResult are re-exported from the root entry. Note that several of the sub-types they reference (ResolvedAndroidMetaData, AndroidLifecyclePublisherInfo, DevClientInfo, IosLifecyclePublisherInfo, IosDevClientInfo) are not re-exported from the autolink barrel, so these results are only partially usable by external consumers.
AndroidLinkResult
export interface AndroidLinkResult {
registryCode: string;
lifecycleCode: string;
activityHooksCode: string;
behaviorsCode: string;
linkedBehaviors: string[];
gradleDependencies: string[];
debugGradleDependencies: string[];
permissions: string[];
debugPermissions: string[];
features: AndroidFeatureEntry[];
services: AndroidServiceEntry[];
metaData: ResolvedAndroidMetaData[];
metaDataWarnings: string[];
linkedModules: string[];
linkedLifecyclePublishers: string[];
lifecyclePublishers: AndroidLifecyclePublisherInfo[];
linkedActivityHooks: string[];
devClient?: DevClientInfo;
}
IosLinkResult
export interface IosLinkResult {
podfileEntries: string[];
debugPodfileEntries: string[];
usageDescriptions: Record<string, string>;
debugUsageDescriptions: Record<string, string>;
backgroundModes: string[];
bgTaskIdentifiers: string[];
registryCode: string;
lifecycleCode: string;
appDelegateHooksCode: string;
componentRegistryCode: string;
linkedComponents: string[];
linkedModules: string[];
linkedLifecyclePublishers: string[];
lifecyclePublishers: IosLifecyclePublisherInfo[];
linkedAppDelegateHooks: string[];
devClient?: IosDevClientInfo;
}
Referenced-but-not-exported types
The named value re-exports above use option and result types that are defined and exported in their own modules but are not pulled into the package's root barrel — so they are not importable from @sigx/lynx-cli. They are documented here for completeness.
PrebuildOptions
export interface PrebuildOptions {
android?: boolean; // default true
ios?: boolean; // default true
clean?: boolean; // bypass fingerprint fast-path
cwd?: string; // default process.cwd()
}
DevServerOptions
export interface DevServerOptions {
cwd: string;
port?: string | number; // default 8788
host?: boolean;
logger: Logger;
launchAppId?: string; // Android applicationId to auto-launch w/ dev URL
launchBundleId?: string; // iOS bundleId to auto-launch on booted sims
iosSimulatorName?: string;
selectedTargets?: unknown; // explicit picker/flag target list
verbose?: boolean;
disableDeviceLogs?: boolean;
// ...additional fields
}
AndroidDevice
export interface AndroidDevice {
id: string;
type: 'device' | 'emulator' | 'offline';
model?: string;
}
IosSimulator
export interface IosSimulator {
udid: string;
name: string;
state: string;
runtime: string;
}
IosDevice
export interface IosDevice {
udid: string; // devicectl identifier
name: string;
model?: string;
osVersion?: string;
transport?: string; // 'wired' | 'wireless'
}
DeviceStatus
export interface DeviceStatus {
devices: AndroidDevice[];
lynxGoInstalled: Map<string, boolean>;
appInstalled?: Map<string, boolean>;
adbAvailable: boolean;
iosSimulators: IosSimulator[];
xcrunAvailable: boolean;
iosAppInstalled?: Map<string, boolean>;
iosDevices: IosDevice[];
devicectlAvailable: boolean;
iosDeviceAppInstalled?: Map<string, boolean>;
}
