Describe the bug
There is a memory leak in VariableContextProvider that causes memory to grow continuously with each component re-render. The memory is never released even after garbage collection, and the leak scales with the number of CSS variables passed to the provider.
Reproduction
Repository: https://github.com/alias-mac/nativewind-mem-leak
To reproduce:
- Clone the reproduction repository
- Run
npm install and start the app with npm run ios or npm run android
- Open your memory profiler (Xcode Instruments, Android Studio Profiler, or React DevTools)
- Click the "Clicked X times" button repeatedly (50-100 times)
- Observe memory usage continuously growing without being released
The reproduction includes:
- A
ThemeProvider component using VariableContextProvider with 1000 CSS variables (these are just examples)
- A simple counter component that re-renders on each click
- Components using
className with the CSS variables (e.g., text-primary)
- The leak occurs regardless of animations - tested with and without
animate-pulse
Key files:
/components/ThemeProvider.tsx - Shows VariableContextProvider with many CSS variables
/app/index.tsx - Simple re-rendering component with key={count} to force remounts
/global.css - CSS variable definition with --color-primary: var(--foo-primary)
Expected behavior
Memory should remain stable or grow minimally with re-renders. After garbage collection, memory should return to baseline levels. CSS variable context should be cleaned up when components unmount or update.
Additional context
- Using NativeWind v5 (preview) with Tailwind CSS v4
- The leak appears to be related to how
VariableContextProvider manages CSS variable context internally
- The severity increases with the number of CSS variables passed to the provider (tested with 1000 variables and leaking 20.5kB on each re-render, but our app has about 40kB for this)
- Each re-render appears to create new references that are not properly garbage collected
- Adding
key={count} to force component remounting makes the leak more pronounced
After only 4 "clicks/re-renders" it increased the size of the DictPropertyMap by 38:
We were able to validate that this issue is reproducible in the production version of the app, so it isn't based on the dev mode (with HMR, dev-client or other developer tools enabled).
Describe the bug
There is a memory leak in
VariableContextProviderthat causes memory to grow continuously with each component re-render. The memory is never released even after garbage collection, and the leak scales with the number of CSS variables passed to the provider.Reproduction
Repository: https://github.com/alias-mac/nativewind-mem-leak
To reproduce:
npm installand start the app withnpm run iosornpm run androidThe reproduction includes:
ThemeProvidercomponent usingVariableContextProviderwith 1000 CSS variables (these are just examples)classNamewith the CSS variables (e.g.,text-primary)animate-pulseKey files:
/components/ThemeProvider.tsx- Shows VariableContextProvider with many CSS variables/app/index.tsx- Simple re-rendering component withkey={count}to force remounts/global.css- CSS variable definition with--color-primary: var(--foo-primary)Expected behavior
Memory should remain stable or grow minimally with re-renders. After garbage collection, memory should return to baseline levels. CSS variable context should be cleaned up when components unmount or update.
Additional context
VariableContextProvidermanages CSS variable context internallykey={count}to force component remounting makes the leak more pronouncedAfter only 4 "clicks/re-renders" it increased the size of the
DictPropertyMapby 38:We were able to validate that this issue is reproducible in the production version of the app, so it isn't based on the dev mode (with HMR, dev-client or other developer tools enabled).