Expo Plugins, Nitro Powered Flashlights and Tailwind Fatigue

Issue #23

01 December 2025
5 Minutes

From Coffee Shops to Fat AAR


Brownfield…?

Sounds like a trendy coffee shop next to your local WeWork. It’s not.

“Brownfield” is what we call it when you’re not starting from scratch — you’re building new features on top of an existing codebase.

In contrast to “Greenfield” (blank slate, blue skies, minimal swearing), Brownfield means you inherit someone else’s architectural sins and get to layer your own on top.

In the context of React Native, Brownfield development usually means embedding RN into a native iOS or Android app that already exists — perhaps to rewrite a screen, maybe to prototype faster, or most likely because someone in a product meeting said ‘React Native’ with enough confidence that no one risked looking old-fashioned by pushing back.

It’s a way to bring RN into the fold without rewriting the whole app… though depending on how tangled things are, that might end up being wishful thinking.

You can currently do Brownfield with Expo — integrating an Expo-managed React Native project into a native app — but it comes at a price: a heap of manual setup, touching all the native files you were trying to avoid in the first place. The official Expo docs lay out the steps, but they’re not for the faint of heart.

That’s where expo-brownfield-target steps in.

It’s a Expo plugin (Expo plugins are config-time scripts that modify your native projects during prebuild, letting you customise native code or link native dependencies) that takes your Expo project and packages it up into something a native app can embed — specifically, a fat AAR (explained below) on Android and an XCFramework (XCFramework is a packaging Apple format that supports multiple architectures and platforms in one distributable framework) on iOS.

A fat AAR is an Android library archive that contains multiple build variants in one — e.g. debug and release, all CPU architectures. Think of it as the “all you can eat” buffet of Android packaging. No need for your native Android team to guess which flavour they need. It’s all in there.


So your Expo app becomes an SDK. A neatly bundled, precompiled slice of React Native, ready to be dropped into a native app like any other dependency.

And just when you thought, “Great, more Expo plugins I’ll never use,” Davey — yes, that Davey from the pub (@1804davey) — goes and ships an Expo Speech Transcriber.

On-device transcription for iOS, privacy-respecting and App Store-friendly, as an Expo plugin:


No servers, no streaming, just you, your mic, and a callback.

It wraps Apple’s Speech framework and supports both the legacy SFSpeechRecognizer (iOS 13+) and the newer SpeechAnalyzer (iOS 16+), with a hook-based API that gives you real-time speech-to-text updates as you talk.


Want to transcribe a file instead? It does that too.

It’s the kind of native capability that used to require ejecting and fiddling with entitlements.

Now?

Just install the package, grant a few permissions, and boom — your app is suddenly listening harder than an iPhone when you whisper ‘camping gear’ near it.

👉 expo-speech-transcriber

👉 expo-brownfield-target



The Torch Module You’ll Thank at 2am


Picture this: it’s 2am on a new moon.

The skies are pitch black. You’re fast asleep when — bang! — something crashes outside.

You lunge for your iPhone, conveniently stashed by your pillow, and fire up your custom high-intensity torch app. But no. The devs never upgraded to the new architecture. The app lags. It’s busy serialising JSON over the bridge like it’s 2018, and your flashlight’s stuck in Redux purgatory.

You’re in a pickle.

This is exactly the problem react-native-torch-nitro solves.


Just as we thought the NitroModule wave was slowing down, @irekrog drops react-native-torch-nitro — a minimal, native torch controller built entirely with the new architecture.

React Native Nitro Torch gives you real-time torch control with zero lag. It ships as a hook, with proper TypeScript support, native brightness control (iOS and Android 13+), and state tracking out of the box.


So next time you hear a bang at 2am, don’t worry — with Nitro Torch, you’ll be blinded by the light before fear has a chance to register.

👉 react-native-torch-nitro


The Code Challenge


We’re trying something new: The Code Challenge. Each issue, we’ll drop a small React or React Native puzzle — just enough to keep your edge sharp.

Reply if you like it, nailed the answer, or want something a little spicier — we read every email.

Consider this snippet:


Question:
What’s the order of logs when this component mounts?

Bonus: If you know why?




Before you Go: TailwindCSS - The Extended Cut


This is the third Tailwind library for React Native in just a few months — if you count NativeWind v5 as a release (and we do).

Honestly, at this point, if you’ve not written a Tailwind library for React Native. Are you even in the community?

We’ve got NativeWind (covered in Issue #19), Uniwind (aka: “Tailwind, but make it compiler-friendly”), and now react-native-tailwind from @mgcrea, because the only thing React Native loves more than pixel-perfect design is violently reinventing it.

React Native Tailwind can be set up pretty easily, honestly—just by configuring a Babel plugin:


Then you can start writing code like this and watch the magic of Tailwind in action:


They’ve also got surprisingly solid docs, and they’re not shy about the pitch.

No runtime styling means no JS-side overhead — which, in theory, makes it faster than NativeWind and Uniwind.

That part might sting a bit for Jacek (@jpudysz), the builder of Unistyles and its faster sibling, Uniwind. Uniwind Pro leans hard into performance, with a C++ styling engine and some genuinely slick extras — like animated theme transitions:


Pretty wild, right?

But there’s a catch.

…it also ships a $99 per seat, per year.

So unless you’re fetish is styling performance, or you just like supporting indie devs (which we are all for btw), that price might feel like a bit much — especially with so many competent and free alternatives in the space for example, we mentioned above, NativeWind and React Native Tailwind.

Still, if you’re curious, you can go an apply to their waitlist for Pro, which honestly looks very promising. We’ll see if Jacek can swing a little Cyber Monday something for The React Native Rewind readers.

Because friends don’t let friends pay full price for sexy styling libraries.

👉 react-native-tailwind



The Code Challenge: The answer is A, C, B — because useMemo runs synchronously during render, while useEffect waits until after the DOM paints.

The VaultHitchhiker's Guide
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Take me back to the paradise city, where the grass is green and the girls are pretty, oh, won’t you please take me home…
Made with 👽 tech by Luke Farrell, Seyda and Friosn.