Skip to content

styled() crashes with Maximum call stack size exceeded when wrapping react-native-svg primitives #455

Description

@mo-fouad

Describe the bug

In nativewind@5.0.0-preview.4, the documented v5 third-party-component recipe for react-native-svg throws on first render:

RangeError: Maximum call stack size exceeded (native stack depth)

The same crash also fires when calling useUnstableNativeVariable() from a component rendered inside an SVG tree — so the bug appears to live in the shared observable/effect layer that both APIs route through (useNativeCss → varResolver → reactivity graph), not in styled() itself.

Plain <Svg color={someStaticHex} /> with the color resolved outside of any NativeWind runtime hook renders correctly. Only the NativeWind runtime path crashes.

Versions:

  • nativewind: 5.0.0-preview.4
  • react-native-css: 3.0.7
  • react-native-svg: 15.15.4
  • react-native: 0.85.3
  • react: 19.2.3
  • expo: 56.0.11 (SDK 56)
  • tailwindcss: 4.2.0 (Tailwind v4, @theme {} block)
  • Platform: iOS simulator, Hermes

Reproduction

npx rn-new@latest --nativewind then drop in:

import { styled } from 'nativewind';
import Svg, { Path } from 'react-native-svg';

const StyledSvg  = styled(Svg);
const StyledPath = styled(Path);

export default function App() {
  return (
    <StyledSvg width={24} height={24} viewBox="0 0 24 24" className="text-red-500">
      <StyledPath d="M2 12h20" stroke="currentColor" strokeWidth={2} />
    </StyledSvg>
  );
}

The documented nativeStyleMapping recipe reproduces the same crash:

const StyledSvg = styled(Svg, {
  className: { target: 'style', nativeStyleMapping: { color: 'color' } },
});

Expected behavior

styled(Svg, { className: { target: 'style', nativeStyleMapping: { color: 'color' } } }) should resolve text-… classes to a color value and lift it onto the <Svg color={…}> prop, so stroke="currentColor" on descendants follows the Tailwind text color. This is the v4 cssInterop recipe that the v5 third-party-components guide still points to.

Additional context

Two suspect spots in react-native-css@3.0.7 that fit the symptom (not confirmed by runtime instrumentation):

  1. useNativeCss runs setState during render if testGuards flips. react-native-svg's Svg/Shape class components rebuild prop derivations on every render (extractedProps, SvgTouchableMixin, setNativeProps), so an identity-based guard may flip on every iteration and recurse synchronously.
  2. varResolver's variableHistory only blocks repeating the same variable name — it doesn't catch cycles across different names. Tailwind v4 OKLCH palette colors compile to nested var() chains, which may be enough to trigger that.

Workaround in use: resolve the color from className ourselves via useColorScheme() + a static token map mirrored from our @theme {} block, then pass it as <Svg color={…} />. Inner Path/Circle stay as plain react-native-svg primitives with stroke="currentColor". Works, but duplicates values from CSS and can't read live runtime variables.

What I tried that did not help:

  • Every nativeStyleMapping shape on styled(Svg, …).
  • Wrapping only the outer <Svg> and leaving inner primitives untouched.
  • Calling useUnstableNativeVariable('color-foreground-tertiary') before any SVG primitive renders — still crashes.

Related: #242 — [V5] - styled doesn't work as it worked in V4 — same symptom shape, marked Done in roadmap but not yet in a published preview.

Activity

  1. github-actions commented on Jun 18, 2026

    @github-actions

    👋 Thanks for opening this issue!

    Before our CI can confidently reproduce this bug we'd like a bit more information. The following appear to be missing or incomplete:

    • a public GitHub reproduction repository link

    Please update the issue and provide a public GitHub repository that reproduces the bug end-to-end. The easiest way to scaffold one is:

    • npx rn-new@latest --nativewind
    • npx rn-new@latest --nativewind --expo-router
    • npx rn-new@next --nativewind
    • npx rn-new@next --nativewind --expo-router

    Because the rest of the bug report is complete, our CI will still attempt a reproduction against a freshly-scaffolded next-plain rn-new starter — see the workflow run linked in the follow-up comment. If the bug only shows up in a specific configuration, please attach a repro repo and the workflow will re-run on the next edit / reopen.

    For usage questions please use the Discord or GitHub Discussions.

  2. github-actions commented on Jun 18, 2026

    @github-actions

    ❓ Inconclusive

    Our automated reproduction pipeline could not conclusively judge this bug. See the CI run for the captured evidence. A maintainer will take a closer look.

    ⚠️ This run was against a freshly-scaffolded next-plain rn-new starter because the issue didn't link a repro repository. If your bug only manifests in a specific configuration (extra deps, custom babel/metro config, navigation flow, etc.), please attach a public repro repo and the workflow will re-run on the next edit / reopen.

    Cannot reproduce or refute. The iOS build completed successfully ('** BUILD SUCCEEDED **'), but the app failed to launch due to a CI infrastructure timeout ('Daemon request timed out'). No runtime console output, crash logs, or UI snapshots were captured, so we have no evidence whether the reported stack overflow when wrapping react-native-svg with styled() actually occurs.

    Platform Verdict Evidence
    ios inconclusive Build succeeded but app never launched. agent_device_errors shows 'Daemon request timed out' - no runtime evidence captured (app_console_tail empty, no snapshot, no logs). Cannot determine if the reported 'Maximum call stack size exceeded'

    Automated by .github/workflows/issue-repro.yml using agent-device. Workflow run: https://github.com/nativewind/nativewind/actions/runs/27747937436

  3. jsg2021 commented on Jun 27, 2026

    @jsg2021

    Just attempted to upgrade gluestack v5 and hit this as it includes nativewind v5

  4. github-actions commented on Jul 8, 2026

    @github-actions

    ❓ Inconclusive

    Our automated reproduction pipeline could not conclusively judge this bug. See the CI run for the captured evidence. A maintainer will take a closer look.

    ⚠️ This run was against a freshly-scaffolded next-plain rn-new starter because the issue didn't link a repro repository. If your bug only manifests in a specific configuration (extra deps, custom babel/metro config, navigation flow, etc.), please attach a public repro repo and the workflow will re-run on the next edit / reopen.

    The iOS build completed successfully but the bundler did not produce a main.jsbundle, meaning the user's JavaScript code never ran. Without runtime execution, we cannot confirm whether the reported 'Maximum call stack size exceeded' crash when wrapping react-native-svg primitives with styled() actually occurs.

    Platform Verdict Evidence
    ios inconclusive Build succeeded but no main.jsbundle was embedded (repro_status='bundle-missing'). User JS never executed, so the reported runtime 'Maximum call stack size exceeded' error could not be observed.

    Automated by .github/workflows/issue-repro.yml using agent-device. Workflow run: https://github.com/nativewind/nativewind/actions/runs/28917177742

  5. jsg2021 commented on Oct 8, 2026

    @jsg2021

    Correction to my earlier comment: the overflow I hit after upgrading to gluestack v5 had a different cause. It was a Metro resolver loop between react-native-css and react-native-worklets' bundle mode, and it happened during module init, not when rendering styled() SVGs. I filed that separately as #473, with a workaround. If you see get NativeModules repeated in your stack and use worklets bundle mode, it's probably that one rather than this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

needs reproductionIssue needs a minimal reproduction before it can be worked onv5 stabilityTracking v5 stability for @latest release

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions