LunarCSS

Known Limitations

Current limitations in v0.1.0 and their planned status.

Limitation table

LimitationStatusNotes
First-install Metro cacheRestart with --clear once after npx lunar-css initMetro caches files transformed before the LunarCSS transformer was wired. Subsequent edits (including lunar.config.ts token tweaks) hot-reload normally — see Metro integration. lunar-css init warns about this in its output.
Container queries on mobileSilently droppedNot supported by React Native. @container and @*: modifiers are no-ops on native — no crash, no warning.
OKLCH on mobileClamped to nearest sRGBWide-gamut values lose chroma. culori converts at resolver time. Dev warning emitted when clamping occurs. Use sRGB-safe OKLCH or a hex fallback for precision.
Keyframe animate-* classes (animate-spin, animate-pulse, ...)Out of scopeDrive Reanimated withTiming / withSpring directly. The transition-* / duration-* / ease-* / delay-* utilities ship and emit RN-Web-compatible CSS time strings — see example/app/(tabs)/motion.tsx.
Tailwind v3 resolver parityDeferredThe Tailwind v3 named color palette (22 scales × 11 steps) ships as a fallback in the v4 resolver; v3 modifier/breakpoint semantics remain deferred.
color-mix() on mobileNot supportedPre-compute in lunar.config.ts using concrete hex or OKLCH values.
Arbitrary background image URL classes on mobileSkippedTailwind URL-based background utilities are not applied on native. Use the Image component with a source prop instead.
3rd-party RN componentsUse styledComponent()The Metro transformer rewrites whitelisted RN intrinsics (see STYLE_PROPS_MAP). Wrap any other component with styledComponent(C, { styleProps: [...] }) from lunarcss — works on native and web.
Babel-only pipelineNot supportedThe runtime path is Metro on native and (lunar resolver inside RN-Web's StyleSheet) on web. A standalone Babel plugin with no Metro is not a supported configuration.
Tailwind CSS on webNot usedreact-native-web's View / Text / Pressable strip the className prop at render time, so even a fully configured Tailwind cannot match the preserved class strings on the DOM. The resolver runs on web instead — RN-Web's StyleSheet emits atomic CSS from the resulting style object. One engine, no Tailwind dependency on web.

OKLCH detail

LunarCSS uses culori to convert OKLCH colors to sRGB before passing to StyleSheet. The conversion is:

  1. Parse OKLCH string
  2. Convert to sRGB
  3. Clamp out-of-gamut channels to [0, 1]
  4. Format as hex

In dev mode, a warning is logged when clamping changes the perceptual lightness by more than a small threshold. In production builds, clamping is silent.

3rd-party component detail

The Metro transformer rewrites className (and any number of <x>ClassName siblings — contentContainerClassName, imageClassName, ...) on whitelisted RN components:

View, Text, TextInput, Image, ImageBackground, ScrollView,
FlatList, SectionList, VirtualizedList,
TouchableOpacity, TouchableHighlight, TouchableWithoutFeedback,
Pressable, Modal, SafeAreaView, KeyboardAvoidingView,
ActivityIndicator, Switch

Multi-style components get the corresponding sibling class props automatically (e.g. contentContainerClassNamecontentContainerStyle on ScrollView/FlatList/SectionList/VirtualizedList, imageClassNameimageStyle on ImageBackground).

For 3rd-party components (LinearGradient, BlurView, design-system primitives), wrap with styledComponent:

import { styledComponent } from '@lunar-kit/css'
import { LinearGradient as _LinearGradient } from 'expo-linear-gradient'

const LinearGradient = styledComponent(_LinearGradient)

// Now accepts className on native AND web
<LinearGradient className="rounded-card overflow-hidden" colors={[...]} />

For multi-style-prop third-party components, pass the style prop names:

const BlurView = styledComponent(_BlurView, { styleProps: ['style', 'tintStyle'] })
<BlurView className="rounded-card" tintClassName="bg-zinc-900/60" />

Or use the __lcssTw runtime helper directly:

import { __lcssTw } from '@lunar-kit/css/runtime'
<SomeThirdPartyComponent style={__lcssTw('p-4 bg-primary rounded-lg')} />

Reporting issues

Found a limitation not listed here? Open an issue.

On this page