I just spent nearly 48 hours debugging an error in my Expo Router app that had nothing to do with what the error said.
If youโre using NativeWind + React Navigation + Expo Router โ this post is for you. Save your time and sanity.
๐ฅ The Error
"Couldn't find a navigation context."
If you're here, youโve probably seen this and thought:
"Ah, I mustโve forgotten to wrap something with
NavigationContainer."
"Maybe the layout is off."
"Is React Navigation broken?"
Nope. Everything was wired up correctly.
But navigation still refused to work.
Until I discovered that... NativeWind was silently breaking everything.
๐ก The Real Culprit: CSS Interop Race Condition
Turns out, certain NativeWind class names trigger runtime CSS parsing at render time.
And if youโre using Expo Router, this creates a subtle race condition:
- React Navigation's context hasn't fully initialized yet.
- NativeWind starts processing your
classNamestring. - React components try to access the navigation context.
- Boom. โ
โ ๏ธ Problematic NativeWind Classes
Here are some of the class names that caused issues in my case:
-
shadow-*โ e.g.shadow-sm,shadow-md -
opacity-*โ e.g.opacity-50,opacity-70 -
bg-color/opacityโ e.g.bg-white/15,bg-black/30 -
text-color/opacityโ e.g.text-white/80
They work fine in isolation.
But in an Expo Router layout, just one of these can trigger the bug.
๐ฅ The Symptom
If you're hitting any of these:
-
"Couldn't find a navigation context"errors randomly - App works one minute and crashes the next
- Stack traces point to NavigationContainer setup
- Nothing makes sense anymore
Check your styles.
โ The Fix: Use Inline Styles
Replace the problematic class names with direct style props.
โ Before:
<TouchableOpacity className="bg-white/15 shadow-sm opacity-50">
โ After:
<TouchableOpacity
style={{
backgroundColor: 'rgba(255, 255, 255, 0.15)',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.05,
shadowRadius: 2,
opacity: 0.5
}}
>
This completely solved the issue in my project.
๐งช Tech Stack
This bug showed up in this combo:
- Expo Router v5+
- NativeWind v4+
- React Navigation v6+
- React Native (latest)
๐งต Why This Matters
- The error message is misleading
- Itโs timing-dependent โ the app may break or work based on device speed or render cycles
- You waste hours debugging the wrong thing
โ What I Did
- Stripped it down to a minimal reproducible repo
- Posted the issue to NativeWind GitHub
- Writing this article to save you from going through it too
๐ง Final Thoughts
I love NativeWind.
I love Expo Router.
But the two donโt always play nice โ and when they donโt, it can really mess with your head.
If you hit weird nav context issues in your app:
โ
Check your layout
โ
Then check your NativeWind className
โ
And maybeโฆ just go inline
๐ฌ Have You Seen This?
If youโve hit this bug (or others like it), drop a comment.
If this saved you time, please share it โ I genuinely hope it helps someone avoid what I went through.
Thanks for reading. ๐จ๐พโ๐ป
Tags:
#reactnative #expo #nativewind #reactnavigation #debugging #cssinterop #mobiledev #javascript
Top comments (2)
you just saved me hours of debugging, this is really helpful! I knew nothing was wrong with the navigation setup, but something told me to Google it before digging deeper, and thatโs how I found this. Thanks so much!
This is live saving post. I imagine how long and how difficult it was to discover the memory corruption. Thank you very much, Samuel Joseph for sharing your finding! Your advice is working